为什么 `sudo env "PATH=$PATH"` 会做任何事情?

为什么 `sudo env "PATH=$PATH"` 会做任何事情?

有人能解释一下为什么会这样吗:

sudo env "PATH=$PATH" make install

与此不同:

sudo make install

我最近遇到过一种情况,make install除非像上面那样运行,否则就会失败。错误与 libtool 有关,但那有点偏离主题了——它为什么要做sudo env "PATH=$PATH"任何事情呢?它不应该PATH已经在我的 shell 会话环境中了吗?

答案1

sudo忽略PATH环境中的它是正常的。

当您运行 时sudo some_commandsudo会使用自己的目录集而不是。此目录集可能在配置PATH中的某个位置定义,也可能没有定义( ,)。如果没有明确定义,则表示默认值为sudo/etc/sudoers/etc/sudoers.d/*/etc/sudoers

secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

(这在某种程度上是简化的,其他选项可能会改变这种机制;man 5 sudoers有关详细信息,请参阅)。

不仅sudo使用其自身的来定位可执行文件;还通过继承这个其他的PATH来运行的命令,而不是从 shell 中继承的原始命令。sudoPATHPATH

env foo=bar baz是将变量设置为命令foo的值的一种方法。当您执行barbaz

sudo env "PATH=$PATH" make install

shell 扩展了$PATHsudo重置 的变量env,但在命令行参数env中获取旧的扩展值PATH=…。这样,你就将 注入了PATH的环境中make,从而避免了事实sudo变化PATH( 的另一个值仍然PATH在其他地方很重要:首先sudo使用它来搜索可执行文件)。env

您可能能够使用以下方法获得类似的结果

sudo "PATH=$PATH" make install

但通过这种方式传递的变量会受到 安全策略插件的限制sudo。您对 的操作env不受限制。


比较这些输出(注意鞋底env打印其环境):

export foo=bar
                         env | grep '^foo='
             env foo=qux env | grep '^foo='
sudo                     env | grep '^foo='
sudo foo=baz             env | grep '^foo='
sudo         env foo=qux env | grep '^foo='
sudo foo=baz env foo=qux env | grep '^foo='

另一组进行比较:

                      env | grep '^PATH='
sudo                  env | grep '^PATH='
sudo     "PATH=$PATH" env | grep '^PATH='
sudo env "PATH=$PATH" env | grep '^PATH='

一般而言,结果可能相同也可能不相同,具体取决于您的PATH设置sudo。就您而言,我预计它们会有所不同(因为所涉及的两个命令的工作方式不同)。

相关内容