Linux su 命令:切换用户、登录环境与单条命令

su 使用另一用户和组的身份运行 shell 或命令。不指定用户时通常以 root 为目标;交互式切换一般使用 su --login user,以建立类似目标用户登录时的环境。

普通的 su user 会保留当前目录与部分环境,可能混合两个账号的设置。如果只需要执行一条管理命令,应先考虑能按策略授权的 sudo 命令及 sudoers 规则。以下以 util-linux 的 su 为准,操作前应已有目标账号与相应授权。

su 如何切换执行身份?

su 用替代的用户 ID 和组 ID 执行命令;省略账号时会尝试启动 root 的交互式 shell。它并不意味着调用者无需认证就能取得目标权限。

util-linux 通过可插拔认证模块 PAM(Pluggable Authentication Modules)处理认证、账号和会话管理。要求谁的密码、是否限制某些组、日志写到哪里,都取决于本机 PAM 和安全设置。其他实现不能直接套用全部选项;可对照 util-linux 项目的 su 手册源文件检查安装版本与配置。

基本语法与返回原 shell

语法中的 options、user 和 arguments 是占位说明,方括号表示可选部分:

su [options] [-] [user [arguments...]]

省略用户时尝试切换到 root:

su

普通用户通常需要输入目标 root 账号的密码,而不是自己的密码。账号密码被锁定或 PAM 不允许认证时,知道调用者的密码也不能使切换成功。密码输入可能不显示字符,应按本机提示操作。

切换到具体账号时指定名称,例如已存在且获授权使用的 deploy:

su deploy

在切换后的 shell 执行以下命令,或在没有待输入内容时按 Ctrl+D 发送文件结束符,可退出并返回原 shell。退出后重新核对身份,避免多层 shell 造成混淆。

exit

su 与 su --login 有什么区别?

比较项 su user su --login user
工作目录 通常保留当前目录 尝试进入目标用户的主目录
环境变量 只调整部分变量,可能混合原环境 清理大部分原环境并初始化登录环境
PATH 受本机配置和 PAM 影响 按登录环境初始化,仍受配置影响
shell 启动 通常为交互式非登录 shell 以登录 shell 方式启动
适用场景 明确需要保留部分原环境的情况 一般交互式账号切换

util-linux 手册建议使用明确的 --login,以减少环境混合的副作用。短写 - 具有相同的登录含义;下面两行是两种替代写法,选一行即可,不需要连续执行:

su --login deploy
su - deploy

登录环境会改变哪些内容?

清理与重新设置环境变量

当前 util-linux 手册说明,--login 清除原环境,但保留 TERM、COLORTERM、NO_COLOR 及白名单指定的变量,并初始化 HOME、SHELL、USER、LOGNAME 和 PATH。旧版本支持的保留项可能不同。

这些选项先处理环境,随后 PAM 还可增改变量,目标 shell 的启动文件也会影响最终结果。因此,“登录环境”不代表所有发行版得到完全相同的变量。

检查身份、主目录和工作目录

登录形式会尝试进入目标用户的主目录。成功切换后分别查询:

id
printf '%s\n' "$HOME"
pwd

检查 id 的用户和组是否属于目标账号,HOME 是否指向该账号主目录,pwd 是否为预期目录。HOME 是变量,pwd 是实际工作目录,二者不能互相代替;如果主目录不存在或不可访问,应检查警告与实际 pwd,不能只看提示符。

目标 shell 的初始化规则

登录 shell 按自身规则读取启动文件。Bash 的登录启动与普通交互启动采用不同文件规则,系统和账号配置会进一步改变环境;排查时检查目标账号所用 shell 的手册与配置,不要假定所有 shell 都读取同一份文件。

常用 su 选项

选项 功能 使用条件与注意事项
-、-l、--login 启动登录 shell 一般交互切换优先使用明确的 --login
-c command、--command command 向 shell 传递命令字符串 检查引号、扩展和退出状态
-s shell、--shell shell 指定 shell 目标为受限 shell 且调用者非 root 时会被忽略
-m、-p、--preserve-environment 保留原环境 与 --login 同用时忽略;PAM 仍可修改环境
-w list、--whitelist-environment list 登录时保留列出的变量 逗号分隔;核心账号变量不受白名单保护
-P、--pty 创建独立的伪终端 适合需要终端的交互会话
-g group 指定主组 仅 root 可用
-G group 指定附加组 仅 root 可用,可重复指定;没有 -g 时首个附加组也用作主组

以另一用户运行单条命令

用 -c 传递命令字符串

不需要停留在交互 shell 时,可让目标用户的 shell 执行指定字符串:

su -c 'id' deploy

认证和启动成功后,id 应显示目标账号的身份;命令结束时 su 退出,返回调用 shell。字符串由目标 shell 再次解释,必须区分原 shell 与目标 shell 处理引号、变量和重定向的时机。单引号通常可避免原 shell 先展开其中的变量。

在登录环境运行

需要目标登录环境和主目录时,将 --login 与 -c 组合:

su --login -c 'pwd; id' deploy

分号两侧都在目标 shell 内执行。分号会在前一条命令失败后继续执行下一条,因此要分别检查输出,不能只凭最后一次成功就认为全部成功。不要把外部输入直接拼入高权限命令字符串。

立即保存退出状态

su 通常返回所执行命令的退出状态;命令被信号终止时返回信号值加 128。su 自身在执行请求前发生一般错误时可返回 1,无法执行请求时为 126,找不到请求时为 127;目标 shell 和程序也可返回自己的错误状态。

su -c '/usr/local/bin/check-job' deploy
status=$?
printf 'exit=%s\n' "$status"

/usr/local/bin/check-job 是需要实际准备并审核的任务程序,不是系统保证存在的命令。应紧接 su 保存 $?,否则其他命令会覆盖它;预期看到 exit=0 或非零状态,并结合任务本身的结果判定成功。

默认 shell、指定 shell 与服务账号

查询账号默认 shell

没有其他选择条件时,su 使用目标账号 passwd 记录里的 shell,缺省时回退到 /bin/sh。可用以下命令查询账号记录:

getent passwd deploy

getent 通过本机账号名称服务查询,结果可能来自本地文件或目录服务;最后一列通常是 shell。没有结果时先确认账号和名称服务,不要为解决切换问题直接改写整个 /etc/passwd。

-s 的选择范围

指定其他 shell 的例子:

su -s /bin/sh -c 'id' deploy

选择顺序通常是 -s 指定值、保留环境模式下的 SHELL、目标账号记录、/bin/sh。若目标 shell 不列在 /etc/shells 中,util-linux 将它视作受限 shell;除调用者为 root 外,会忽略 -s 与环境 SHELL。这个定义不能与 Bash 的受限运行模式混为一谈。

尊重服务账号的用途

使用 nologin 或 false 的账号通常不供交互登录。root 能选择其他 shell,并不代表开放交互访问就安全。确需以服务账号执行时,仅运行已授权的必要任务,并优先检查服务管理工具或 systemd 提供的功能,不要为方便排错永久放宽账号设置。

谨慎保留环境变量

--preserve-environment 的含义

该选项保留原环境,不重新设置 HOME、SHELL、USER 和 LOGNAME;与 --login 同用时被忽略:

su --preserve-environment deploy

PAM 仍会进行最终环境调整,所以它不是“所有变量原样传递”的保证。调用者的路径、配置或程序加载设置可能影响目标身份运行的程序;混合环境也可能让文件写入错误位置。只有理解用途与变量影响时才使用。

只保留必要变量

登录模式可以用白名单保留明确需要的变量:

su --login --whitelist-environment=LANG,LC_ALL deploy

列表用逗号分隔。HOME、SHELL、USER、LOGNAME 和 PATH 不受这份白名单保护,仍按登录过程初始化。LANG 和 LC_ALL 也会影响程序行为,应确认目标系统具备对应 locale,并仅传递必要值。

su 与 sudo 如何选择?

比较项 su sudo
主要目的 以替代身份运行 shell 或命令 按安全策略以其他身份执行命令
常见认证 目标用户的密码 调用者自己的密码
权限范围 进入 shell 后可继续使用目标账号权限 可按命令与条件授权,具体取决于策略
记录与审计 认证与会话转换记录,内部命令需另行审计 可经策略和日志插件记录执行请求
适合情况 需要目标账号的交互环境 单条管理命令或明确角色权限

表中认证方式是常见配置,PAM 与 sudo 策略可以改变它。只需运行一条 root 命令时,通常优先考虑按命令授权的 sudo,避免共享目标账号密码;但授予 shell 或功能过宽的程序也可能扩大权限,不能仅凭使用 sudo 就认定满足最小权限。

为什么无法切换到 root?

密码认证被锁定

有些系统锁定 root 密码认证,采用 sudo 管理。此时在 su - 提示中输入当前用户密码不会因此成功。若已有适当 sudo 授权,且确实需要完整管理 shell,可以使用:

sudo -i

单条任务应优先执行获准的具体命令,管理 shell 用完及时退出。不要为了绕过 su 失败而自行启用 root 密码。

PAM 或组策略限制

检查 /etc/pam.d/su 的实际策略;登录形式还可能采用 /etc/pam.d/su-l。组限制、附加认证及会话条件都可能影响结果。向管理员提供任务、目标账号和错误信息,不要通过弱化 PAM 来取得权限。

账号与目录状态异常

账号过期、密码锁定、主目录缺失、受限 shell、文件访问权限都可能造成失败或警告。管理员应结合 getent 查询、账号管理工具和认证日志确认具体原因。密码锁定不等于所有其他认证路径都必然被禁止,需看实际策略。

root 自动化中使用 runuser

以指定账号直接运行任务

util-linux 为 root 脚本等已具备权限的场景推荐 runuser:它无需 set-user-ID 安装,不询问密码,并使用独立 PAM 配置。

runuser -u backup -- /usr/local/bin/backup-job

这需要 root、已存在的 backup 账号与经过审核的 backup-job 程序;示例会实际运行备份任务,不是无副作用的探测。runuser 不会给普通用户额外权限,也不自动保证任务安全或模拟完整登录环境。程序、配置、路径和文件权限仍需审查。

不需要 PAM 会话时

若只需调整用户、组及权限属性,并不需要 PAM 会话,util-linux 手册还建议考虑 setpriv。它直接操作凭据与安全属性,应由理解主组、附加组、能力及目标程序需求的管理员设计,不能当作普通用户绕过授权的工具。

用伪终端分隔交互会话

--pty 提供什么?

--pty 创建独立的伪终端,由 su 中继输入输出,让目标会话不直接共享原终端。需要交互终端时,它有助于降低共享终端所涉及的命令注入风险:

su --pty --login deploy

它提供的是终端分隔,不是文件系统、网络或账号权限的隔离;目标程序仍按授予的身份与权限运行。

登录 shell 不等于完整系统登录会话

即便使用 --login,su 也不会从 systemd 的这一视角建立完整的真实登录会话。需要用户服务或完整会话边界时,应按任务检查 systemd-run、machinectl 等工具的运行模式与授权;不能只改用 su - 就假定所有会话设施已具备。

使用时的安全检查

  • 不要共享 root 或其他账号的密码,也不要将密码放入命令行、历史、脚本或管道。
  • 进入目标 shell 后核对 id、HOME 与 pwd,完成后退出,避免长期开着 root shell。
  • 执行前检查选项、目标路径及通配符由哪个 shell 展开。
  • 核对 PAM、journal 与认证日志的实际记录方式和保留策略。

su 的认证记录不等于目标 shell 内每条命令的审计。若有逐条追踪需求,需要额外的审计和日志设计;sudo 启动的 shell 内部命令也不能仅凭最初的 sudo 请求日志完整还原。日志同样应避免收集密码和令牌。

常见问题与排查方向

现象 可能原因 检查方法
Authentication failure 目标密码、账号状态或 PAM 限制 确认目标账号及认证策略,查看相应日志
切换后找不到命令 目标 PATH 或安装状态不同 用 command -v 检查具体程序,按需查看 PATH
工作目录没有变化 未使用登录选项,或主目录不可访问 核对 --login、警告信息、目录权限与 pwd
账号环境混杂 普通 su 保留了原环境的一部分 只检查必要的 HOME、USER 等变量,避免公开完整 env
指定 shell 没有运行 受限 shell 或调用条件限制 查询 getent passwd 与 /etc/shells,不要直接放宽配置

常见问题

su 应输入谁的密码?

通常是目标用户的密码。root 调用或 PAM 采用其他认证方式时可能不同。输入不显示字符很常见,应根据本机提示判断;不要把调用者自己的密码当成 root 密码反复尝试。

su 与 su - 有什么区别?

省略用户时二者都以 root 为目标。普通 su 通常保留当前目录和部分环境;su - 请求登录环境并尝试进入 root 主目录。util-linux 更建议明确使用 --login,以减少环境混合。

切换后如何确认当前用户?

id 可查看用户与组,实际身份与有效身份不同时也会显示差异;只需有效用户名可用 whoami。不要只凭 shell 提示符判断身份。

能把 su 密码写进脚本吗?

不应这样做,密码可能经文件、进程信息或日志泄漏。root 自动化可审查 runuser 方案;普通用户的授权任务应设计最小权限 sudoers 或专用服务,同时审核程序、参数和依赖。

操作要点

交互切换通常使用 su --login user,单条任务使用 su -c 并正确处理引号和退出状态。切换后确认身份与目录,结束后退出。仅需有限管理任务时考虑按策略授权的 sudo,root 的跨账号自动化则检查 runuser 与目标任务的实际条件。