"su", "sudo -s", "sudo -i", "sudo su"之间有什么区别?

我已经从手册中阅读了,但是我看不出区别。

su - 切换用户ID或成为超级用户

sudo -s [command]

-s(shell)选项会运行由SHELL环境变量设置的shell,如果未设置,则运行passwd(5)中指定的shell。如果指定了命令,则将其传递给shell执行。否则,将执行一个交互式shell。

sudo -i 在手册中没有描述


11此外,在不受信任的shell中,也不要使用su user登录,应该使用su - user。请参考http://unix.stackexchange.com/q/7013/8250。 - Lekensteyn
@Lekensteyn 哇,太棒了的例子。谢谢你让我笑出声:) - törzsmókus
1永远记住古老的戒律:不可妄称root之名! - törzsmókus
不是说sudo -i是坏的,但你肯定可以用它搞砸事情。 - Kellen Stuart
相似问题:https://askubuntu.com/questions/376199/sudo-su-vs-sudo-i-vs-sudo-bin-bash-when-does-it-matter-which-is-used - Reinier Post
6个回答

这些命令之间的主要区别在于它们限制对其功能的访问方式。 su(即“替代用户”或“切换用户”)- 正是如此,它启动另一个具有目标用户特权的shell实例。为了确保您有权执行此操作,它会要求您输入目标用户的密码。因此,要成为root用户,您需要知道root密码。如果您的计算机上有多个用户需要以root身份运行命令,则他们都需要知道root密码 - 请注意,它将是相同的密码。如果您需要从其中一个用户撤销管理员权限,则需要更改root密码,并仅告知那些需要保留访问权限的人 - 这样会变得混乱不堪。
sudo(嗯...助记符是什么?超级用户DO?)完全不同。它使用一个配置文件(/etc/sudoers),列出了哪些用户具有特定操作的权限(以root身份运行命令等)。当调用时,它会要求输入启动它的用户的密码,以确保终端上的人确实是在/etc/sudoers中列出的“joe”。要撤销某个人的管理员权限,只需编辑配置文件(或从列在该配置文件中的组中删除该用户)。这样可以更清晰地管理权限。
因此,在许多基于Debian的系统中,root用户没有设置密码,即无法直接登录为root。
此外,/etc/sudoers还允许指定一些附加选项,例如用户X只能运行程序Y等。
通常使用的sudo su组合的工作原理如下:首先,sudo会要求您输入您自己的密码,如果您被允许这样做,它将以超级用户的身份调用下一个命令(su)。因为su是由root调用的,所以它不需要您输入目标用户的密码。因此,如果您被/etc/sudoers文件授予了超级用户访问权限,sudo su允许您以另一个用户(包括root)的身份打开一个shell。

3我从来没见过su被译为“切换用户”,而是一直作为超级用户; 默认行为是不带其他用户名称(虽然这样也没问题)。根据维基百科: “su命令,早在1974年就被称为超级用户[1],也被称作“替代用户”,“欺骗用户”或“设置用户”,因为它允许更改与当前终端(窗口)相关联的账户。” - dr jimbob
7@dr jimbob:你说得对,但我发现“切换用户”更能准确描述它的功能,尽管从历史上来看,它代表的是“超级用户”。我也很高兴地发现维基百科的文章与我的回答非常相似——我以前从未见过这篇文章 :) - Sergey
16"su" 的官方含义是 "替代用户"。请参见:"man su"。 - Angel O'Sphere
2@AngelO'Sphere:有趣的是,Ubuntu的man手册中根本没有提到"substitute"这个词。而gnu.org(http://www.gnu.org/software/coreutils/manual/html_node/su-invocation.html)上的man手册确实说了"su: Run a command with substitute user and group ID"。我认为gnu.org是一个权威的来源 :) - Sergey
@Serqey嗯,Linux并不是Unix :D或许那个小字被遗漏了。目前手头没有Solaris或SunOS机器,但我稍后会在我的Mac上进行检查。据我所知(大约25年前),它一直被称为"替代用户"。 - Angel O'Sphere
2What about sudo su? - Kaz Wolfe
@Whaaaaaat:我在我的回答中添加了一个段落。 - Sergey
@Sergey:给你点赞。所以sudo su的作用类似于sudo -s吗? - Kaz Wolfe
@Whaaaaaat:嗯,它们是相似的,尽管我不确定是否有与登录 shell、环境等相关的任何差异。 - Sergey
1Debian在安装过程中要求输入root密码。因此,你关于“基于Debian的系统中root没有密码”的说法是不准确的。 - Thomas Ward
1根据这个链接:https://wiki.debian.org/Root - 在Debian中,密码是可选的。我稍微修改了我的回答,谢谢 :) - Sergey
1@Sergey 可选的 是的,但你仍然需要 root 来安装 sudo。虽然是同样的基本操作。安装程序镜像也不喜欢你不输入 root 密码。我已经设置了很多次了... - Thomas Ward
1@Sergey - 你提供的答案没有明确解释为什么用户应该选择su -而不是其他选项,比如su -s或su -i以及它们之间的区别。此外,sudo su -似乎并不是最佳选择,因为它只是为了切换用户而提升权限,这样就不需要输入密码。为什么不直接选择su -、sudo -i或sudo -s呢? - Motivated
1@有动力:sudo susudo -isudo -s在实际用途上非常相似,sudo su与其他变体一样有效。只需使用您喜欢的命令。而纯粹的su(或者你说的su -)行为完全不同,区别在我的回答中已经解释了。 - Sergey
1@Sergey - 你的意思是说使用sudo su与sudo -i或sudo -s没有任何区别或优势,反之亦然,无论是单独使用还是组合使用都一样吗? - Motivated
2根环境初始化的方式存在一些细微差别,其他答案中已经讨论了一些细节。但往往这些差异并不重要。 - Sergey

sudo允许您以root权限在自己的用户帐户中运行命令。su允许您切换用户,以便实际上作为root登录。

sudo -s以root权限运行一个shell。sudo -i还获取了root用户的环境。

要查看susudo -s之间的区别,请在每个命令后执行cd ~然后pwd。在第一种情况下,您将位于root的主目录中,因为您是root。在第二种情况下,您将位于自己的主目录中,因为您具有root权限。

关于这个确切问题的更多讨论在这里


27"你以 root 权限是你自己" 并不是实际发生的情况 :) 实际上,无法同时成为 "以 root 权限的你自己" - 你要么是 root,要么是你自己。试着在两种情况下输入 whoamicd ~ 结果不同的原因是 sudo -s 没有设置 $HOME 环境变量。 - Sergey
2@Sergey,whoami命令显示你是“root”,是因为你以sudo的方式运行了该命令,所以在该命令执行期间,你看起来像是root用户,但根据sudoers文件的权限设置,你可能仍然没有完全的root访问权限。 - Octopus
1@章鱼:我想说的是,在Unix系统中,一个进程只能有一个用户标识符(UID),而该UID决定了进程的权限。你不能以“拥有root权限的自己”的身份运行程序,程序要么使用你的UID,要么使用root的UID(0)。 - Sergey
5关于“根据sudoers文件,您可能仍然没有完全的root访问权限”:sudoers文件控制谁可以作为另一个用户运行哪个命令,但这发生在命令执行之前。然而,一旦您被允许以root身份启动进程,正在运行的进程将具有root的UID,并且对系统具有完全访问权限,sudo无法限制它。再次强调,您始终是您自己或root用户,不存在“半斤八两”的情况。因此,如果sudoers文件允许您以root身份运行shell,那么该shell中的权限与“正常”的root shell不可区分。 - Sergey

这个答案是我在这个问题的副本上的答案,放在这里作为标准答案,以便人们能够找到它!
sudo -i和sudo -s之间的主要区别是:
- sudo -i会给你root环境,即你的~/.bashrc会被忽略。 - sudo -s会给你用户的环境,所以你的~/.bashrc会被尊重。
下面是一个例子,你可以看到我在我的~/.bin/目录中有一个名为lsl的应用程序,通过sudo -s可以访问,但通过sudo -i无法访问。还请注意,Bash提示符会随着sudo -i而改变,但不会随着sudo -s而改变。
dotancohen@melancholy:~$ ls .bin
lsl

dotancohen@melancholy:~$ which lsl
/home/dotancohen/.bin/lsl

dotancohen@melancholy:~$ sudo -i

root@melancholy:~# which lsl

root@melancholy:~# exit
logout

dotancohen@melancholy:~$ sudo -s
Sourced .bashrc

dotancohen@melancholy:~$ which lsl
/home/dotancohen/.bin/lsl

dotancohen@melancholy:~$ exit
exit

尽管sudo -s可以方便地提供你熟悉的环境,但出于两个原因,我推荐使用sudo -i
  1. 视觉上提醒你处于“root”会话。
  2. “root”环境很少受到恶意软件的感染,比如在.bashrc中插入的恶意代码。

我注意到sudo -s似乎无法处理/etc/profile,或者我在/etc/profile.d/中的任何内容.. 你有什么想法为什么会这样? - Northstrider
@dotancohen - 你说的sudo -s提供了一个用户熟悉的环境是什么意思? - Motivated
@dotancohen - 命令sudo -s已经提供了视觉提示,所以我很好奇为什么sudo -i是更好的选择。 - Motivated
1也许自原文写作以来情况有所改变,关于~/.bashrc的内容可能不再严格正确。因为你的~/.profile很可能会引用.bashrc,而sudo -i会引用~/.profile - Cas

  • su 要求输入 root 密码,切换为 root 用户,并打开一个交互式的非登录 shell。
  • su - 要求输入 root 密码,切换为 root 用户,并打开一个交互式的登录 shell

  • sudo -s 询问您的密码,成为超级用户,打开一个交互式非登录shell。
  • sudo -i 询问您的密码,成为超级用户,打开一个交互式登录shell。

最佳实践是使用上述两个命令。


  • sudo su 询问您的密码,暂时成为root用户以root身份运行su
  • sudo su - 询问您的密码,暂时成为root用户以root身份运行su -

因此,在这种情况下,您使用sudo运行su,而无需知道root的实际密码。结果与susu -相同。


4登录和非登录shell之间有什么区别? - Pilot6
4另一个问题? - Ravexina
1最佳做法是使用上述两个命令。为什么呢? - Henrique

su要求输入用户"root"的密码。
sudo要求输入您自己的密码(并且还会检查您是否被允许以root身份运行命令,这是通过/etc/sudoers配置的 - 默认情况下,所有属于"admin"或"sudo"组的用户帐户都被允许使用sudo)。
sudo -s以root身份启动一个shell,但不会更改您的工作目录。sudo -i模拟登录到root帐户:您的工作目录将为/root,并且root的.profile等文件将被视为登录时加载。

1为了使答案更完整:sudo -s几乎等同于su($HOME不同),而sudo -i等同于su - - DJCrashdummy
@DJCrashdummy - 你为什么说“几乎相等”?有什么不同吗? - Motivated

在Ubuntu或相关系统中,我不太需要传统的超级用户意义上的susudo更好地处理了这种情况。然而,在配置sudoers会很愚蠢的一次性情况下,su非常适用。
例如,如果我正在使用Live CD/USB修复我的系统,我通常会挂载我的硬盘和其他必要的东西,并且chroot进入系统。在这种情况下,我的第一个命令通常是:
su - myuser  # Note the '-'. It means to act as if that user had just logged in.

那样的话,我不是以root身份运行,而是以我的普通用户身份运行,然后根据需要使用sudo命令。