【问题标题】:lzma command not found when executing shell script only under sudo仅在 sudo 下执行 shell 脚本时找不到 lzma 命令
【发布时间】:2017-02-16 11:11:44
【问题描述】:

我正在 SUSE 服务器中构建项目源代码。 项目 build.sh 调用“lzma”命令来压缩内核。 项目 build.sh 需要“sudo”才能访问某些系统命令。 但是我试过执行“sudo ./build.sh”,shell总是报错:“lzma: command not found.”

我可以使用我的用户帐户在 shell 中执行“lzma”。它工作正常。 我还编写了一个名为“test.sh”的测试shell脚本,它调用“lzma”命令。 我发现如果我用 "sudo" 执行 "test.sh" ,它会失败并显示相同的错误消息。 但是如果我在没有“sudo”的情况下执行“test.sh”,它就可以正常工作。 为什么?

【问题讨论】:

  • sudo 重置环境变量作为安全措施。这意味着您的PATH 可能会被中断。

标签: linux shell sudo


【解决方案1】:

sudo 中的“找不到命令”几乎总是由 PATH、LD_LIBRARY_PATH 等环境变量(如果缺少的不是可执行文件而是它需要的共享库)等环境变量被更改的结果。

你可以通过你的环境变量显式地传递工作值:

sudo PATH="$PATH" ./test.sh

【讨论】:

  • 谢谢,它有效。这是否意味着 sudo 会在 PATH 的目录中找到 bin 文件?
  • 对此的简短回答是肯定的。 (有一个更长的答案来区分由sudo 本身完成的路径查找和由它调用的其他工具完成的路径查找——sudo 实际上在第一次启动时会执行自己的 PATH 查找,因为它的配置文件根据完全限定的路径将二进制文件列入白名单,但是在sudo 启动程序之后,然后是该程序自己的方法——或者它调用的 C 标准库调用(如execvp)——从那时起负责 PATH 查找)。
【解决方案2】:

Sudo 使用的路径与您的用户帐户不同。

编辑(见 cmets)

尝试并执行:

type lzma

假设输出内容类似于“/usr/bin/lzma”,然后将该输出复制到您的 sudo 命令中,例如(例如):

sudo /usr/bin/lzma

这应该可以解决问题。如果要以 root 身份运行它,还应该将 lzma 的完整路径写入 shell 脚本。

编辑 2:

或者,正如 Charles Duffy 在他的回答中提到的那样,如果您尝试以 SUDO 或其他用户身份执行文件,您可以保留所有内容,只需在命令中使用 PATH="$PATH"

【讨论】:

  • type lzmawhich lzma 更全面——前者告诉你shell 实际在执行什么;后者只告诉你路径中的第一个。 通常这些东西是相同的,但并不总是如此。
  • 也就是说,我倾向于建议——如果有人打算修改脚本——以不降低其可移植性的方式对其进行修改。例如,将PATH=$PATH:/usr/local/bin 放在脚本的顶部不会阻止它在您的lzma 命令/usr/local/bin 中的其他系统上工作,而硬编码/usr/local/bin/lzma 意味着您的脚本在其他任何地方都不起作用。 (我意识到您在示例中使用了/usr/bin,但在/etc/sudoers 中配置了默认PATH 而没有/usr/bin 几乎闻所未闻)。
  • (...跳回到我的第一条评论:考虑用户的点文件是否包含 lzma() { /opt/something/bin/lzma "$@"; }; export -f lzma - 导出的函数将可用于没有 sudo 的脚本,但 which 将无法找到它,除非/opt/something/bin 在 PATH 中,而 type 会正确识别它)。
猜你喜欢
  • 1970-01-01
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多