如何让`sudo` 保留$PATH?

hug*_*omg 164 sudo path

我有一个程序安装在 /opt 下的自定义目录中。为了更容易运行它,我编辑了我的 bashrc 以将所述目录添加到我的路径中:

export PATH=$PATH:/opt/godi/bin:/opt/godi/sbin
Run Code Online (Sandbox Code Playgroud)

如果我想在没有 sudo 的情况下运行程序,这很好用。但是,如果我尝试使用 sudo 运行它,它会因“找不到命令”错误而失败。

$ sudo godi_console
sudo: godi_console: command not found
Run Code Online (Sandbox Code Playgroud)

使用 sudo 后检查 PATH 变量表明它不包括我作为普通用户所拥有的相同 PATH:

$ sudo sh
# echo $PATH                 
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Run Code Online (Sandbox Code Playgroud)

为什么 PATH 不一样?难道我做错了什么?我在 Debian Jessie 上,如果它有所作为。

我尝试的一件事是直接调用 /opt/godi/sbin/godi_console,将绝对路径传递给可执行文件。不幸的是,这在这种特殊情况下没有帮助,因为 godi_console 本身取决于正确设置的 PATH。

Sté*_*las 206

你总是可以这样做:

sudo env "PATH=$PATH" godi_console
Run Code Online (Sandbox Code Playgroud)

作为 Debian 上的一项安全措施,/etc/sudoerssecure_path选项设置为安全值。

注意:

sudo "PATH=$PATH" godi_console
Run Code Online (Sandbox Code Playgroud)

Wheresudo将包含=字符的前导参数本身视为环境变量赋值,也可以在其环境中godi_console您的 $PATH(而不是 )一起运行secure_path,但不会影响sudo的可执行文件的搜索路径,因此无助sudo于找到那个godi_console

  • 顺便说一下,`sudo "PATH=$PATH" godi_console` 在 CentOs7 中不起作用。需要环境 (6认同)
  • 我最喜欢这个答案,因为它避免了全局更改设置的需要(即保留最小特权原则) (5认同)
  • @StéphaneChazelas `sudo "PATH=$PATH" godi_console` 真的有用吗?`sudo` 接受 `VAR=value` 参数,影响它运行的命令的环境,但与 `env` 或 `bash` 不同,`sudo` 似乎不会让它影响它查找命令的方式。我(最近)只在 Ubuntu 16.04 上测试过这个。但我尝试将 `exempt_group` 选项添加到 `sudoers` 中(仅用于测试——我不认为这是一个解决方案!),结果很有启发性。`PATH="$PATH" sudo some-command` 形式的命令开始工作,但 `sudo PATH="$PATH" some-command` 形式的命令 *仍然* 没有。 (2认同)
  • @ballsatballsdotballs。由于该别名应该只影响您的交互式 shell,所以应该是相对无害的。 (2认同)
  • 我只是为这些类型的情况创建了一个名为 psudo 的别名,其中:alias psudo="sudo env \"PATH=$PATH\""。然后我的正常 sudo 使用不受影响。 (2认同)

mic*_*lbn 55

您还可以将默认 PATH 设置为 /etc/sudoers

使用编辑文件 visudo

并将该行更新为您希望的任何内容: Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin


MAQ*_*MAQ 26

默认情况下,SUDO 正在重置环境变量。

查看其手册和名为 env_reset 的选项。

您只需要在 /etc/sudoers 中禁用它。

  • 凉爽的!在 Ubuntu 中,您可以使用 visudo 并注释掉 secure_path 和 env_reset 行。使系统的安全性大大降低,所以要小心。 (7认同)

unt*_*ore 11

sudo --preserve-env=PATH env [command]
Run Code Online (Sandbox Code Playgroud)

这个 ovverrides secure_path 在我这边


Seb*_*bMa 9

这有效:

sudo $(which your_command)
Run Code Online (Sandbox Code Playgroud)

调用我gps列出 Nvidia GPU 进程的脚本的示例:

$ sudo gps
sudo: gps: command not found
$ sudo $(which gps)
  PID TTY          TIME CMD
 9922 tty7     02:42:47 Xorg
Run Code Online (Sandbox Code Playgroud)

解释 :

$ set -x;sudo $(which gps);set +x
++ which gps
+ sudo /home/xyztuv/myScripts/shl/gps
  PID TTY          TIME CMD
 9922 tty7     02:42:39 Xorg
+ set +x
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案,因为它不会让您暴露在被劫持的路径上的其他命令。这里的所有其他答案都有以 root 身份运行其他可执行文件的风险。 (2认同)