![`sudo` 如何在路径中搜索可执行文件?](https://linux22.com/image/546348/%60sudo%60%20%E5%A6%82%E4%BD%95%E5%9C%A8%E8%B7%AF%E5%BE%84%E4%B8%AD%E6%90%9C%E7%B4%A2%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6%EF%BC%9F.png)
我在 Ubuntu 10.10 上使用 rubygems (1.3.7) 和需要 root 权限的 gem。当我将我的设置与安装了 rubygems 1.3.6 的 ubuntu 9.10 进行比较时,我发现了以下区别gem environment
:
1.3.7 / 10.10- EXECUTABLE DIRECTORY: /var/lib/gems/1.8/bin
1.3.6 / 09.10- EXECUTABLE DIRECTORY: /usr/bin
无论我是否使用,输出都是相同的sudo
。为了解决这个问题(我不知道为什么它一开始就不同),我尝试修改我的路径变量。
我的问题是,在哪里sudo
查找可执行文件?如果我安装 gem(使用sudo
),可执行文件/var
显然会放在路径中。我将此路径添加到我的~/.profile
和/etc/environment
文件中,但我无法sudo
执行可执行文件。
如果我运行:
$ gemname
它能正确运行我的工具。$ sudo gemname
它只是告诉我command not found
。$ sudo echo $PATH
它做显示正确的路径。$ sudo -i gemname
它运行正确。$ sudo sudo -V
表明 PATH 已被保留。
是否sudo
尊重~/.profile
和/或/etc/environment
?如果是这样,为什么当目录显示在环境变量中时,他们找不到我的可执行文件$PATH
?
我已经阅读了的文档sudo
,我也搜索并浏览了大量关于 stackoverflow 和 serverfault 的主题(例如如何覆盖 sudo 中的 PATH 环境变量?,但我的示例显示$PATH
包含正确的路径),但他们从未真正展示如何通过运行 gem sudo
。
答案1
请注意,在第三个命令中,shell 在$PATH
sudo 看到它之前就展开了,因此输出是 shell 的路径,而不是 sudo 看到的 PATH。你想要的是类似sudo echo \$PATH
或 的内容sudo sh -c 'echo $PATH'
。
除此之外,请查看sudo(8)
手册页的“安全注意事项”部分。我相信 Ubuntusudo
使用 SECURE_PATH 构建选项进行构建。在 的输出中查找“用于覆盖用户的 $PATH 的值”行sudo sudo -V
。
sudo -i
模拟初始登录,因此将读取类似这样的文件.profile
(尽管它读取哪些文件取决于 root 的 shell 是什么)。如果没有-i
,它将从调用者的环境中继承保留的环境变量,并采用我上面提到的 PATH 清理。
至于路径最初为何改变,我怀疑这是开发人员故意为之。请参阅更多讨论bugs.debian.org。
答案2
让我们分部分来看:
- gemname 它可以正确运行我的工具。
没关系 :)
- sudo gemname 它只是告诉我没有找到命令。
gemname
不在你的$PATH
- sudo echo $PATH 它确实显示了正确的路径。
这很酷:变量扩展发生在 bash 运行程序之前。因此,当你运行这个程序时,它会扩展到你的用户$PATH
前调用 sudo,因此传递给 sudo 的行更像是:
$ sudo echo "/usr/bin:/bin:"
- sudo -i gemname 它正确运行。
sudo -i
作为登录 shell 运行并遵守.profile
and/or .login
。正如man
页面所述:
它还会初始化环境,保持 DISPLAY 和 TERM 不变,设置 HOME、MAIL、SHELL、USER、LOGNAME 和 PATH,以及 Linux 和 AIX 系统上的 /etc/environment 的内容。所有其他环境变量都将被删除。