为什么通过 sudo 和 su 运行时 PATH 变量不同?

Jus*_*ier 52 linux shell sudo path environment-variables

在我的 Fedora VM 上,使用我的用户帐户运行时/usr/local/bin,我的路径中有:

[justin@justin-fedora12 ~]$ env | grep PATH
 PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/justin/bin
Run Code Online (Sandbox Code Playgroud)

同样在运行时su

[justin@justin-fedora12 ~]$ su -
Password: 
[root@justin-fedora12 justin]# env | grep PATH
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/justin/bin
Run Code Online (Sandbox Code Playgroud)

但是,运行 via 时sudo,此目录不在路径中:

[root@justin-fedora12 justin]# exit
[justin@justin-fedora12 ~]$ sudo bash
[root@justin-fedora12 ~]# env | grep PATH
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/sbin:/bin:/usr/sbin:/usr/bin
Run Code Online (Sandbox Code Playgroud)

为什么运行 via 时路径会不同sudo

mat*_*tdm 51

看看/etc/sudoers。Fedora(以及 RHEL,还有 Ubuntu 和类似的)中的默认文件包括这一行:

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
Run Code Online (Sandbox Code Playgroud)

这可确保在 sudo 下运行二进制文件时您的路径是干净的。这有助于防止出现此问题中提到的一些问题。如果您没有/sbin并且/usr/sbin在您自己的路径中,这也很方便。


小智 11

该命令su -将执行 root 用户配置文件并采用该用户的环境,包括路径等。sudo不这样做。

如果您想sudo表现得像su -然后使用sudo -i [command将执行用户配置文件的选项

如果你想su -表现得像sudo那么不要使用连字符 - 只需使用su [command]


ken*_*orb 7

您可以通过运行来检查原因(不同)sudo sudo -V

例如在 Linux 上运行:

$ sudo sudo -V | grep PATH
Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Run Code Online (Sandbox Code Playgroud)

注:在MacOS / BSD,只需运行:sudo sudo -V

由于某些 Linux 发行版中的默认安全策略插件,上述列表受到限制。


进一步解释man sudoers如下:

如果secure_path设置了该选项,其值将用于PATH环境变量。

secure_path- 用于从 sudo 运行的每个命令的路径。如果你不相信运行 sudo 的人有一个健全的PATH环境变量,你可能想要使用它。

另一个用途是如果您想让“根路径”与“用户路径”分开。exempt_group选项指定的组中的用户不受secure_path. 默认情况下未设置此选项。

如果是这种情况,您可以通过运行sudo visudo和编辑配置文件并修改您的secure_path(添加由 分隔的额外路径:)或将您的用户添加到exempt_group(这样您就不会受到secure_path选项的影响)来更改它。

或者为了传递用户的PATH临时信息,您可以运行:

sudo env PATH="$PATH" my_command
Run Code Online (Sandbox Code Playgroud)

您可以通过以下方式检查:

sudo env PATH="$PATH" env | grep ^PATH
Run Code Online (Sandbox Code Playgroud)

另请参阅:如何进行sudo保存$PATH


环境可能与 , 不同的其他原因sudo是因为您可以env_resetsudoers文件中启用选项。这会导致在新的最小环境中执行命令。

因此,您可以使用env_keep选项(出于安全原因不推荐)来保留用户的环境变量:

Defaults        env_reset
Defaults        env_keep += "PATH PYTHONPATH"
Run Code Online (Sandbox Code Playgroud)


Sea*_*mus 2

问:“为什么通过 sudo 运行时路径会不同?”

也许最好的解释可以在Command environment以下部分中找到man 5 sudoers

由于环境变量可以影响程序行为,因此 sudoers 提供了一种方法来限制要运行的命令继承用户环境中的哪些变量。sudoers 有两种不同的方式来处理环境变量。

本节继续解释如何修改对传递或阻止的环境变量的限制sudo。这些默认限制将因操作系统和发行版而异。因此,您的第一站应该是sudo -V了解环境变量的状态。从提示符处运行此命令root;例如:

$ sudo -i
# sudo -V

 ... a long list ...

Run Code Online (Sandbox Code Playgroud)

此输出显示系统的每个环境变量,按其状态分组:removedpreservedcheck

如果您的PATH环境变量位于已删除的列表中,您可以使用以下行更改它:

Defaults env_keep += "path PATH"
Run Code Online (Sandbox Code Playgroud)

您可以sudoers通过编辑以下内容将此行添加到您的文件配置中:

Defaults env_keep += "path PATH"
Run Code Online (Sandbox Code Playgroud)

另一种选择 -对我的思维方式来说更清晰的是,将其作为“代码片段”添加到/etc/sudoers.d- 如果它存在的话。如果它不存在,您可以通过将该行添加#includedir /etc/sudoers.d到文件的尾部来创建它sudoers

这与编辑过程基本相同sudoers;“代码片段可以按如下方式创建和编辑:

$ sudo visudo 
Run Code Online (Sandbox Code Playgroud)

您可以通过再次运行来验证更改是否已设置sudo -V(根据root提示!);在这种情况下,您的 PATH 变量现在应该位于保留列表中。