`sudo` 如何在路径中搜索可执行文件?

`sudo` 如何在路径中搜索可执行文件?

我在 Ubuntu 10.10 上使用 ruby​​gems (1.3.7) 和需要 root 权限的 gem。当我将我的设置与安装了 ruby​​gems 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 在$PATHsudo 看到它之前就展开了,因此输出是 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 运行并遵守.profileand/or .login。正如man页面所述:

它还会初始化环境,保持 DISPLAY 和 TERM 不变,设置 HOME、MAIL、SHELL、USER、LOGNAME 和 PATH,以及 Linux 和 AIX 系统上的 /etc/environment 的内容。所有其他环境变量都将被删除。

相关内容