当你以普通用户登录,而某项任务需要 root 权限或切换到另一个账户时,在 Linux 上有两种实用选择:使用 su 切换到该用户,或者通过 sudo 以提升的权限运行单条命令。su 工具(substitute user 的缩写)是两者中较古老的一个,也是许多系统管理员在需要以另一用户身份获得完整 Shell 时仍然会使用的命令。
在当前登录会话中,使用 su 是切换到管理员账户最简单的方式。当 root 用户被禁止通过 SSH 或图形登录管理器登录系统时,它尤其方便。如果你只想以提升的权限运行单条命令,请改看 sudo 命令指南。
本指南通过实际示例讲解如何使用 su 命令,以及它与 sudo 的区别。
语法
su 命令的基本语法如下:
su [OPTIONS] [USER [ARGUMENT...]]
不带任何选项调用时,su 的默认行为是运行一个以 root 身份的交互式 Shell:
su
系统会提示你输入 root 密码,验证通过后,运行该命令的用户会临时变为 root。
要确认用户已切换,可以使用 whoami 命令:
whoami
root
要切换到另一个用户账户,可将用户名作为 su 的参数传入。例如,切换到用户 tyrion 可以输入:
su tyrion
要以另一用户身份启动登录 Shell:
su - tyrion
登录 Shell 与非登录 Shell
当你运行不带 - 选项的 su 时,SHELL 和 HOME 环境变量取自目标用户在 /etc/passwd 中的记录,但当前目录和其余环境不会更改。这意味着 PATH 变量仍然包含原用户的目录。
调用 su 时最常用的选项是 -(即 -l、--login)。它会启动一个登录 Shell,其环境与真实登录完全一致,包括将当前目录切换到目标用户的家目录:
su -
在大多数情况下,你应当使用 su - 而不是普通的 su,以获得干净的环境。
选项
su 命令接受以下选项:
运行指定 Shell
要运行 passwd 文件中定义的之外的一个 Shell,可使用 -s(--shell)选项。例如,切换到 root 并运行 zsh Shell:
su -s /usr/bin/zsh
如果目标用户的账户使用了受限 Shell(即该 Shell 不在 /etc/shells 列表中),那么除非你是以 root 身份调用 su,否则 su 会同时忽略 -s 选项和 SHELL 变量。
保留环境变量
要保留调用用户的完整环境(HOME、SHELL、USER 和 LOGNAME),可使用 -p(--preserve-environment)选项:
su -p
当使用 - 选项时,-p 会被忽略。
运行单条命令
要以目标用户身份运行命令而不启动交互式 Shell,可使用 -c(--command)选项。例如,以 root 身份调用 ps 命令:
su -c 'ps aux'
要以指定用户身份运行命令:
su -c 'whoami' tyrion
如果命令字符串包含空格或特殊字符,应将其用引号引起来。
使用 sudo su 获取 root 权限
在 Ubuntu 等一些 Linux 发行版中,出于安全考虑,root 用户账户默认是禁用的。这意味着 root 没有设置密码,普通的 su 无论你在提示符下输入什么都会失败。
解决方法是给 su 命令加上 sudo 前缀,并输入当前登录用户的密码:
sudo su -
如果用户被授予了 sudo 权限,su 就会以 root 身份被调用。由于此时进程已经以 root 身份运行,su 不会再索要自己的密码。运行 sudo su - 然后输入你的用户密码,与运行 su - 并输入 root 密码效果相同。
去掉 - 会给你一个停留在当前工作目录的 root Shell:
sudo su
你也可以用这种方式切换到普通账户,这在你不知道该用户密码时很有用:
sudo su - tyrion
sudo 命令本身就能打开 root Shell,完全不涉及 su。-i 选项会以 root 用户的环境运行一个交互式登录 Shell:
sudo -i
-s 选项会启动一个不运行登录 Shell 的 root Shell:
sudo -s
这四条命令都会让你停留在 root 提示符下,但它们在 Shell 选择、启动文件和当前目录上有所不同:
| Command | Shell | Reads root’s login files | Working directory |
|---|---|---|---|
| sudo su | Root’s configured shell, non-login | No | Unchanged |
| sudo -s | Calling user’s shell, non-login | No | Unchanged |
| sudo su - | Root’s configured shell, login | Yes | Root’s home, usually /root |
| sudo -i | Root’s configured shell, login | Yes | Root’s home, usually /root |
sudo -s 命令使用 SHELL 变量或调用用户配置的 Shell,而其余形式使用 root 配置的 Shell。登录形式会读取 root 的登录文件并切换到 root 的家目录(通常是 /root)。
当你需要 root 登录 Shell 时,优先使用 sudo -i,因为它直接调用 root 的登录 Shell,而不是再启动 su 作为第二个程序。对于日常管理工作,应给单条命令加上 sudo 前缀,这样 sudo 的权限策略与命令日志都会作用于每次调用。
sudo 与 su 的区别
sudo 与 su 的主要区别如下:
- 密码:su 需要目标用户的密码;sudo 需要你自己的密码。
- 访问控制:sudo 可以细粒度地控制用户能运行哪些命令(在 /etc/sudoers 中配置);su 则给予对目标用户账户的完全访问权限。
- 审计:sudo 会记录通过 sudo 调用的命令;su 只记录用户切换了账户,而在新 Shell 中运行的命令不会被 su 单独记录。
- root 密码:sudo 消除了在多名管理员之间共享 root 密码的需要。
故障排查
su: 认证失败——你为目档用户输入了错误的密码,或者该目标账户没有设置密码。在 Ubuntu 及其他默认锁定 root 账户的发行版上,普通的 su 永远会失败,因为不存在 root 密码。请改用 sudo su - 或 sudo -i;如果你确实需要直接的 su 访问,可用 sudo passwd root 设置 root 密码。
运行 su 后执行 root 命令提示 command not found——普通的 su 通常会保留你原有的 PATH,不过 /etc/login.defs 中的 ALWAYS_SET_PATH 或 PAM 配置可能会改变这一行为。如果你普通用户的 PATH 中不包含 /sbin 或 /usr/sbin,那么即便你是 root,useradd、fdisk、shutdown 等命令也会因 command not found 而失败。使用 su - 以获得 root 的完整 PATH,或者直接用命令的绝对路径调用,例如 /usr/sbin/useradd。
su: 用户 <name> 不存在,或该用户条目缺少必需字段——你准备切换到的用户账户不在 /etc/passwd 中。请仔细检查拼写,并用 id <name> 或 getent passwd <name> 确认该账户确实存在。
su -c 运行了错误的命令,或意外拆散了参数——命令字符串在 su 看到之前正被你当前的 Shell 解析。请将整个命令用单引号引起来,例如 su -c 'systemctl restart nginx',这样目标用户的 Shell 会把它当作一个整体参数接收。
无法退出回到原用户——exit 命令(或按 Ctrl+D)会离开当前 Shell。如果 su 被嵌套了多次,你可能需要多次运行 exit 才能回到最初的会话。
快速参考
如需可打印的快速参考,请查看 su 速查表。
| Task | Command |
|---|---|
| Switch to root | su |
| Switch to root (login shell) | su - |
| Switch to another user | su username |
| Run a command as root | su -c 'command' |
| Use a specific shell | su -s /bin/zsh |
| Preserve environment | su -p |
| Switch to root via sudo | sudo su - |
| Switch to another user via sudo | sudo su - username |
| Sudo login shell | sudo -i |
常见问题
su 与 su - 有什么区别?su 会切换到目标用户,但保留大部分当前环境,包括 PATH 和当前工作目录。su - 则以目标用户的完整环境启动一个完整的登录 Shell。
su 与 sudo 有什么区别?su 将你的整个会话切换到另一用户,并需要该用户的密码。sudo 使用你自己的密码以提升的权限运行单条命令(或打开一个 Shell)。
既然我已经是 root,为什么 su 还要问密码?如果你已经是 root,su 不会索要密码。如果它仍然提示,你很可能处于一个只是看起来像 root Shell 的嵌套 Shell 中,例如前一次 sudo -i 留下了不寻常的提示符。在继续排查前,先运行 whoami 确认你到底是谁。
如何退出 su 会话?输入 exit 或按 Ctrl+D 离开当前 Shell,返回到上一个用户。如果你连续运行了多次 su,请重复该步骤,直到回到最初的会话。
如何限制哪些用户可以使用 su?可通过 PAM 配置 su 的限制,通常在 /etc/pam.d/su 中。要仅允许特定组的成员,可使用带显式组的 pam_wheel.so,例如 auth required pam_wheel.so group=wheel。在启用该规则前,请确认该组存在且至少有一名管理员属于它,因为错误的 PAM 配置可能会阻断 su 访问。各发行版默认值不同,因此请阅读本地 PAM 文件中的注释,而不要直接取消某条通用行的注释。
sudo su 与 su - 有什么区别?两者都会给你一个 root Shell。sudo su 使用你自己的密码进行认证,并停留在当前目录、使用非登录 Shell;而 su - 需要 root 密码,并在 root 的家目录(通常是 /root)中启动一个干净的登录 Shell。在 root 账户被锁定的系统(如 Ubuntu)上,只有 sudo 形式可用。
以不同用户身份运行命令的 su 选项的长格式是什么?是 --command,即 -c 的长形式。例如 su --command 'whoami' tyrion 会以 tyrion 身份运行单条命令,而不是打开交互式 Shell。
总结
su 命令可让你切换到另一个用户账户,并以该用户的权限运行命令,当你需要以另一用户身份获得完整的交互式 Shell 时,它就是合适的工具。对于日常管理工作,sudo 通常因其访问控制与审计能力而成为更好的选择,因此建议将本指南与 Linux 中的 sudo 命令一文配合使用。