What's the difference between login as user and changing users using su through root?
SSH starts a login shell. su
, by default does not.
In particular, this means that the ~/.profile
(or similar file) for that user is not sourced. So changes made in ~/.profile
won't take effect. It might also be the case that:
- even if you start a login shell, different changes were made in root's
~/.profile
, which might pollute the user's environment./etc/profile
and/etc/profile.d/*
may apply settings differently for different users (not by default, though)
- there might be different settings for different users in SSH configuration.
PAM configuration is different. For example,
/etc/pam.d/ssh
has:session required pam_env.so user_readenv=1 envfile=/etc/default/locale
whereas
/etc/pam.d/su
has:session required pam_env.so readenv=1 envfile=/etc/default/locale
This means SSH loads
~/.pam_environment
, butsu
doesn't. This is a big one, since~/.pam_environment
is the shell-independent place for environment variables, and it is applied if you login from the GUI, the TTY or SSH.
To start a login shell, run either of:
su - <username>
sudo -iu <username>
Example:
# su muru -c 'sh -c "echo $HOME $PATH"'
/home/muru /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
# su - muru -c 'sh -c "echo $HOME $PATH"'
/home/muru /home/muru/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
# sudo -iu muru sh -c 'echo $HOME $PATH'
/home/muru /home/muru/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# sudo -u muru sh -c 'echo $HOME $PATH'
/root /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# ssh muru@localhost 'echo $HOME $PATH'
/home/muru /home/muru/devel/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Even with SSH, if you run a command instead of starting a shell, a login shell won't be run (note the absence of ~/bin
in the SSH test, which is present in su -
and sudo -i
). To get the true result, I will run my shell as a login shell:
# ssh muru@localhost '$SHELL -ilc "echo \$HOME \$PATH"'
/home/muru /home/muru/bin:/home/muru/devel/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
This is also why sudo su
and sudo -s
are crappy ways of getting a root shell. Both these ways are polluted by the environment.
Related:
- Unix & Linux: su vs sudo -s vs sudo -i vs sudo bash