iTranslated by AI
People who use 'sudo su' are mostly old-timers
This random post I wrote got a "decent" reaction.
Come to think of it, I started using sudo over 20 years ago, and since my memory was a bit fuzzy, I decided to look it up.
Summary
| Current Directory | Inherited Environment Variables | Shell | Login Shell | |
|---|---|---|---|---|
| su | Unchanged | Almost all | Default shell | No |
| su - | User's home | Only TERM
|
Default shell | Yes |
| sudo su | Unchanged | Some | Default shell | No |
| sudo su - | User's home | Only TERM
|
Default shell | Yes |
| sudo -s | Unchanged | Some |
$SHELL at execution |
No |
| sudo -i | User's home | Some | Default shell | Yes |
sudo su and sudo -s are almost the same. The shell being executed may differ.
sudo su - and sudo -i are also almost the same. In terms of clearing environment variables, sudo su - is more thorough.
You don't necessarily need to read the rest.
su
A command to execute a shell as another user. I call it "su" or "S-U."
It seems it originally stood for "super user," "switch user," or "substitute user."
By default, it switches to root, but you can specify a username as an argument to switch to that user.
The shell configured as the default for the new user is executed.
The password to enter is the password of the new user.
~% su
Password: (root password)
root@hostname:/home/tmtms# id
uid=0(root) gid=0(root) groups=0(root)
root@hostname:/home/tmtms#
~% su hoge
Password: (hoge's password)
hoge@hostname:/home/tmtms$ id
uid=1001(hoge) gid=1001(hoge) groups=1001(hoge)
hoge@hostname:/home/tmtms$
Arguments added after the username are passed to the shell.
~% su hoge -c id
Password: (hoge's password)
uid=1001(hoge) gid=1001(hoge) groups=1001(hoge)
~%
The current directory does not change.
If the shell is bash, it executes /etc/bash.bashrc and ~/.bashrc. However, since it is not a login shell, /etc/profile and ~/.profile are not executed.
Environment variables HOME and SHELL are set. If switching to a user other than root, USER and LOGNAME are also set. Other environment variables are inherited.
When I actually tried su on Ubuntu, PATH and MAIL were also changed.
There are settings like the following for PATH in /etc/login.defs, but the values are different, so it doesn't seem to be this.
#
# *REQUIRED* The default PATH settings, for superuser and normal users.
#
# (they are minimal, add the rest in the shell startup files)
ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
It's written in /etc/pam.d/su and /etc/environment as follows, and this seems to be what's taking effect.
# This module parses environment configuration file(s)
# and also allows you to use an extended config
# file /etc/security/pam_env.conf.
#
# parsing /etc/environment needs "readenv=1"
session required pam_env.so readenv=1
# locale variables are also kept into /etc/default/locale in etch
# reading this file *in addition to /etc/environment* does not hurt
session required pam_env.so readenv=1 envfile=/etc/default/locale
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
MAIL is also affected by this in /etc/pam.d/su. Probably.
# Defines the MAIL environment variable
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
# in /etc/login.defs to make sure that removing a user
# also removes the user's mail spool file.
# See comments in /etc/login.defs
#
# "nopen" stands to avoid reporting new mail when su'ing to another user
session optional pam_mail.so nopen
su -
Similar to su, a shell is executed as the new user, but it is executed as a login shell.
The current directory also becomes the new user's home directory.
If the shell is bash, files such as /etc/profile, ~/.bash_profile, ~/.bash_login, and ~/.profile are executed.
Environment variables are cleared, but there is one exception: the TERM environment variable is inherited. This is because if TERM were cleared, terminal control would break...
sudo
A command to execute commands as another user. I call it "su-doo" (sudo).
While su executes a shell, sudo allows you to specify the command to execute as an argument.
The password to enter is the password of the original user (the user who executed sudo).
~% sudo id
[sudo] password for tmtms: (original user's password)
uid=0(root) gid=0(root) groups=0(root)
~%
By default, it switches to root, but you can specify a user with the -u option.
~% sudo -u hoge id
[sudo] password for tmtms: (original user's password)
uid=1001(hoge) gid=1001(hoge) groups=1001(hoge)
~%
The current directory does not change.
Various environment variables are inherited (described later).
Since you only need to enter your own password, it is convenient to be able to execute commands as root without knowing the password of other users, especially root.
That said, we can't have just anyone executing commands as root, so the people who can use sudo are restricted in /etc/sudoers.
In Ubuntu, users belonging to the admin group or the sudo group can use sudo.
On Ubuntu, no password is set for root, so su cannot be used. If you need to perform tasks as root, you use sudo.
Once you enter your password for sudo, you can execute it without a password for a certain amount of time (15 minutes by default), so it's convenient not to be asked for a password every time when executing sudo consecutively. You can reset the timer with sudo -K.
Sometimes accidents happen where you preemptively type your password thinking you'll be asked, but since 15 minutes haven't passed since the last execution, the password string ends up being displayed in the terminal...
sudo -s
It's nice to be able to just prefix a command with sudo when you want to run it as root, but sometimes you want to use shell features (like wildcards or redirection) as root, so you want to run an interactive shell with sudo.
In those cases, the aforementioned sudo su is sometimes used.
sudo su executes su with root privileges, and su executes a shell as root, so as a result, you end up launching a shell as root using sudo.
~% sudo su
[sudo] password for tmtms: (original user's password)
root@hostname:/home/tmtms#
Well, that's fine, but I feel like sudo bash would be simpler. Although it requires more typing.
~% sudo bash
[sudo] password for tmtms: (original user's password)
root@hostname:/home/tmtms#
Now, sudo has an option called -s, which allows you to start a shell. This seems better than sudo su.
However, unlike su, the shell launched in this case uses the value of the SHELL environment variable at the time sudo was executed.
~% sudo -s
[sudo] password for tmtms: (original user's password)
hostname#
sudo -i
sudo also has an -i option, which, like su -, starts the shell as a login shell.
The shell is properly the default shell of the new user, and the current directory also becomes the new user's home directory.
% sudo -i
[sudo] password for tmtms: (original user's password)
root@hostname:~#
sudo Environment Variables
Running sudo -V as root displays various sudo settings. The environment variables that are inherited are also output here.
~% sudo -V
Sudo version 1.9.5p2
Sudoers policy plugin version 1.9.5p2
Sudoers file grammar version 48
Sudoers I/O plugin version 1.9.5p2
Sudoers audit plugin version 1.9.5p2
~% sudo sudo -V
Sudo version 1.9.5p2
configure options: --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-option-checking --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --libexecdir=${prefix}/lib/x86_64-linux-gnu --disable-maintainer-mode --disable-dependency-tracking -v --with-all-insults --with-pam --with-fqdn --with-logging=syslog --with-logfac=authpriv --with-env-editor --with-editor=/usr/bin/editor --with-exampledir=/usr/share/doc/sudo/examples --with-timeout=15 --with-password-timeout=0 --with-passprompt=[sudo] password for %p: --without-lecture --with-tty-tickets --disable-root-mailer --enable-admin-flag --with-sendmail=/usr/sbin/sendmail --with-rundir=/run/sudo --libexecdir=/usr/lib --with-sssd --with-sssd-lib=/usr/lib/x86_64-linux-gnu --enable-zlib=system --with-selinux --with-linux-audit --enable-tmpfiles.d=yes MVPROG=/bin/mv
Sudoers policy plugin version 1.9.5p2
Sudoers file grammar version 48
Sudoers path: /etc/sudoers
Authentication methods: 'pam'
Syslog facility if syslog is used for logging: authpriv
Syslog priority if syslog is used for logging: notice
Syslog priority to use when user authentication fails: alert
Send mail if user authentication fails
Send mail if user is not in sudoers
Lecture user the first time they run sudo
Require user to be authenticated by default
Root may run sudo
Allow gathering of some information to display useful error messages
Require fully qualified hostnames in the sudoers file
visudo honors the EDITOR environment variable
Set the LOGNAME and USER environment variables
Length at which to wrap log file lines (0 for no wrap): 80
Authentication timestamp timeout: 15.0 minutes
Password prompt timeout: 0.0 minutes
Number of password attempts: 3
umask to use (0777 means use user's value): 022
Path to mail program: /usr/sbin/sendmail
Flags for mail program: -t
Address to send mail to: root
Subject line for mail: *** SECURITY information for %h ***
Incorrect password message: Sorry, try again.
Path to lecture status directory: /var/lib/sudo/lectured
Path to authentication timestamp directory: /run/sudo/ts
String to use for password prompt: [sudo] password for %p:
Default user to run commands as: root
Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
Path to editor used by visudo: /usr/bin/editor
When to require a password for 'list' pseudo-command: any
When to require a password for 'verify' pseudo-command: all
Close file descriptors >= 3 before executing command
Set the collection of environment variables to default
Environment variables to check for safety:
TZ
TERM
LINGUAS
LC_*
LANGUAGE
LANG
COLORTERM
Environment variables to remove:
*=()*
RUBYOPT
RUBYLIB
PYTHONUSERBASE
PYTHONINSPECT
PYTHONPATH
PYTHONHOME
TMPPREFIX
ZDOTDIR
READNULLCMD
NULLCMD
FPATH
PERL5DB
PERL5OPT
PERL5LIB
PERLLIB
PERLIO_DEBUG
JAVA_TOOL_OPTIONS
SHELLOPTS
BASHOPTS
GLOBIGNORE
PS4
BASH_ENV
ENV
TERMCAP
TERMPATH
TERMINFO_DIRS
TERMINFO
_RLD*
LD_*
PATH_LOCALE
NLSPATH
HOSTALIASES
RES_OPTIONS
LOCALDOMAIN
CDPATH
IFS
Environment variables to preserve:
XAUTHORIZATION
XAUTHORITY
PS2
PS1
PATH
LS_COLORS
KRB5CCNAME
HOSTNAME
DPKG_COLORS
DISPLAY
COLORS
Locale to use when parsing sudoers: C
Compress I/O logs using zlib
Directory in which to store input/output logs: /var/log/sudo-io
File in which to store input/output logs: %{seq}
Add records to utmp/utmpx file when a pty is allocated
PAM service name to use: sudo
PAM service name to use for login shells: sudo
Attempt to authenticate using PAM credentials for the target user
Create a new PAM session for the command to be run
Performing PAM account validation management
Enable sudoers netgroup support
Verify that the parent directory is writable when editing files with sudoedit
Allow command execution even if audit log file cannot be written to
Allow command execution even if log file cannot be written to
Log entries longer than this will be split into multiple syslog messages: 960
File mode for I/O logs: 0600
Use file descriptors instead of paths when executing commands: digest_only
Type of authentication timestamp: tty
Ignore case when looking up usernames
Ignore case when looking up group names
Log when a command is allowed by sudoers
Log when a command is denied by sudoers
Sudo log server timeout in seconds: 30
Enable SO_KEEPALIVE socket option on sockets connected to the log server
Verify that the log server's certificate is valid
Set PAM remote user to the user running sudo
Format of logs to generate: sudo
Enable SELinux RBAC support
Local IP address and netmask pairs:
xxx.xxx.x.xxx/xxx.xxx.xxx.x
xxx.xxx.x.xxx/xxx.xxx.xxx.x
xxx.xx.x.x/xxx.xxx.x.x
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxx/xxxx:xxxx:xxxx:xxxx::
xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/xxxx:xxxx:xxxx:xxxx::
xxxx::xxxx:xxxx:xxxx:xxxx/xxxx:xxxx:xxxx:xxxx::
xxxx:xxxx:xxxx:xxxx:xxxx:xxx:xxxx:xxxx/xxxx:xxxx:xxxx:xxxx::
xxxx::xxxx:xxxx:xxxx:xxxx/xxxx:xxxx:xxxx:xxxx::
Sudoers I/O plugin version 1.9.5p2
Sudoers audit plugin version 1.9.5p2
Discussion