What's the difference between sudo su - postgres and sudo -u postgres?
PostgreSQL users peer authentication on unix sockets by default, where the unix user must be the same as the PostgreSQL user. So people frequently use su
or sudo
to become the postgres
superuser.
I often see people using constructs like:
sudo su - postgres
rather than
sudo -u postgres -i
and I'm wondering why. Similarly, I've seen:
sudo su - postgres -c psql
instead of
sudo -u postgres psql
Without the leading sudo
the su
versions would make some sense if you were on an old platform without sudo
. But why on a less than prehisoric UNIX or Linux would you use sudo su
?
Solution 1:
Forget sudo su
There is no benefit to using sudo su
, it's an anachronistic habit from when people were used to using su
. People started tacking sudo
in front when Linux distros stopped setting a root password and made sudo
the only way to access the root account. Rather than change their habits, they just used sudo su
. (I was one of them until relatively recently when using boxes with sudoers
configs forced me to change my habit).
Use sudo -u
For a login shell, sudo -u postgres -i
is preferable to sudo su - postgres
. It doesn't require that the user have root access in /etc/sudoers
, they only need the right to become user postgres
. It also lets you enforce better access controls.
For command execution
sudo -u postgres psql -c "SELECT 1"
is superior to the alternative:
sudo su - postgres -c "psql -c \"SELECT 1\""
in that you don't have to double-escape quotes and other shell metacharacters as well as the other security advantages of not needing root. You'll probably accidentally land up writing:
sudo su - postgres -c psql -c "SELECT 1"
sometimes, which won't work properly.
Finally, it's way easier to set environment variables via sudo
, e.g.
sudo PATH=/usr/pgsql-9.3/bin:$PATH -u postgres /usr/pgsql-9.3/bin/initdb -D /var/lib/pgsql/testcluster
than via su
. (Here, the PATH
setting is required so that initdb
can find the correct postgres
executable).
So. Forget the su
command exists. You don't need it anymore. To break the habit, alias it to something that'll print an error. (Some init and package setup scripts still use su
so you can't remove it, though).
See also:
- What's the difference between "sudo su -" and "sudo -i"?
- What's the magic of the "sudo su"?
- What is the difference between sudo -i and sudo su -