有人能解释一下为什么会这样吗:
sudo env "PATH=$PATH" make install
与此不同:
sudo make install
?
我最近遇到过一种情况,make install
除非像上面那样运行,否则就会失败。错误与 libtool 有关,但那有点偏离主题了——它为什么要做sudo env "PATH=$PATH"
任何事情呢?它不应该PATH
已经在我的 shell 会话环境中了吗?
答案1
sudo
忽略PATH
环境中的它是正常的。
当您运行 时sudo some_command
,sudo
会使用自己的目录集而不是。此目录集可能在配置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 中继承的原始命令。sudo
PATH
PATH
env foo=bar baz
是将变量设置为命令foo
的值的一种方法。当您执行bar
baz
sudo env "PATH=$PATH" make install
shell 扩展了$PATH
。sudo
重置 的变量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
。就您而言,我预计它们会有所不同(因为所涉及的两个命令的工作方式不同)。