使用sudo时出现“命令未找到”,但不使用sudo时可以正常运行该命令

9

我已经在我的GOPATH中安装了一个二进制文件dep,路径为/home/me/go/bin

运行dep可以成功执行该二进制文件,但是运行sudo dep会出现sudo: dep: command not found的错误:

$ dep
Dep is a tool for managing dependencies for Go projects

Usage: "dep [command]"
...

Use "dep help [command]" for more information about a command.

$ sudo dep
sudo: dep: command not found

路径不是问题的关键:
$ echo $PATH
/usr/share/Modules/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/var/lib/snapd/snap/bin:/home/me/.local/bin:/home/me/bin:/home/me/.local/bin:/home/me/bin:/home/me/go/bin:/home/me/.local/bin:/home/me/bin:/home/me/go/bin

$ sudo echo $PATH
/usr/share/Modules/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/var/lib/snapd/snap/bin:/home/me/.local/bin:/home/me/bin:/home/me/.local/bin:/home/me/bin:/home/me/go/bin:/home/me/.local/bin:/home/me/bin:/home/me/go/bin

这两个路径是相同的,因为 mesuperuser 都引用了关键目录 /home/me/go/bin

为什么在不使用 sudo 的情况下运行 dep 会成功,但使用 sudo 却显示 command not found


3
在运行sudo命令之前,$PATH会被扩展;请尝试使用sudo sh -c 'echo "$PATH"'代替。 - chepner
1个回答

7
默认情况下,sudo不会将用户原始的PATH传递到超级用户进程中,而是使用系统上定义的一些默认PATH。如果您运行“sudo env”命令查看sudo进程的整个环境,就能轻松看到这一点:
$ sudo env | grep PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin
您尝试的“sudo echo $PATH”命令没有任何作用,因为shell先将$PATH转换为该变量具有的任何值,然后才调用命令(sudo),所以它只会打印您外部环境的值 :-)
要使您的PATH在sudo内部传递,可以执行以下操作:
$ sudo PATH=$PATH sh -c env | grep PATH
PATH=/usr/share/Modules/bin:/usr/lib64/ccache:/home/nyh/gaps:/home/nyh/bin:/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/sbin:/sbin:/usr/games:/usr/local/android-sdk-linux/tools:/usr/local/android-sdk-linux/platform-tools:/home/nyh/google-cloud-sdk/bin
基本上,我传递给sudo运行的命令首先将PATH设置为$PATH(请记住,$PATH在sudo运行之前由外壳扩展,因此它是我想要的实际路径!),并运行一个shell(将使用这个新PAT)来运行“env”。正如您所看到的,env确实获取了正确的路径。您可以将“env”替换为您想要运行的任何程序。

好的回答。话虽如此(如果您不介意在系统路径区域“乱扔”),只需将它们放入 /usr/local/bin 以用于自定义二进制文件,或者放入 /usr/local/sbin 以用于需要 sudo 的自定义脚本,这是一个简单的解决方案。该特定区域 /usr/local/- 是许多发行版 $PATH 语句中常见的“第一次命中”。这意味着在 /bin//sbin/ 之前首先查找该区域。 - B. Shea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接