使用sudo时出现“命令未找到”的错误

219

我在我的主目录下有一个名为foo.sh的脚本。

当我进入这个目录并输入./foo.sh时,会出现

-bash: ./foo.sh: 权限被拒绝

当我使用sudo ./foo.sh时,会出现

sudo: foo.sh: 找不到命令

为什么会发生这种情况,我该如何解决?

11个回答

205

权限被拒绝

为了运行脚本,文件必须具有可执行权限位设置

要完全理解Linux 文件权限,可以研究chmod命令的文档。chmod是"改变模式"(change mode)的缩写,它用于更改文件的权限设置。

要阅读本地系统的chmod文档,请从命令行运行man chmodinfo chmod。一旦阅读并理解了chmod文档,您就应该能够理解运行...的输出。

ls -l foo.sh

...它将列出文件所有者、组所有者以及其他既不是文件所有者也不是文件所属组成员的人(该权限组有时被称为“世界”或“其他”)的读取、写入和执行权限。

以下是解决权限被拒绝错误的简要摘要。

$ ls -l foo.sh                    # Check file permissions of foo
-rw-r--r-- 1 rkielty users 0 2012-10-21 14:47 foo.sh 
    ^^^ 
 ^^^ | ^^^   ^^^^^^^ ^^^^^
  |  |  |       |       | 
Owner| World    |       |
     |          |    Name of
   Group        |     Group
             Name of 
              Owner 

所有者有读写权限rw,但-表示缺少可执行权限

chmod命令可以解决此问题。(组和其他人只能对文件进行读取,无法写入或执行)

$ chmod +x foo.sh               # The owner can set the executable permission on foo.sh
$ ls -l foo.sh                  # Now we see an x after the rw 
-rwxr-xr-x 1 rkielty users 0 2012-10-21 14:47 foo.sh
   ^  ^  ^

从Linux的角度来看,现在可以将foo.sh视为可执行文件。

使用sudo命令会导致“命令未找到”

使用sudo命令相当于以超级用户或root用户身份运行命令。

根据情况,root用户无法找到您的命令,原因可能是root的PATH环境变量不包括foo.sh所在的目录。因此,找不到该命令。

PATH环境变量包含一系列用于搜索命令的目录。每个用户根据自己的需求设置自己的PATH变量。要查看它设置为什么,请运行:

env | grep ^PATH

以下是运行上述env命令的示例输出,首先作为普通用户运行,然后使用sudo作为root用户运行:

rkielty@rkielty-laptop:~$ env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

rkielty@rkielty-laptop:~$ sudo env | grep ^PATH
[sudo] password for rkielty: 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin
注意,尽管相似,但在此情况下,非特权用户(rkielty)和超级用户所包含的 PATH 中的目录 不相同
根用户的 PATH 变量中不存在 foo.sh 所在的目录,因此会出现 命令未找到 的错误。

1
@Nakilon,如果您将问题详细说明并提出,我应该能够为您进一步排除故障。问题可能是哪个 shell(您的第一个命令 shell 还是由 sudo 启动的 shell)已经评估了 $PWD。 - Rob Kielty
27
怎样才能让 sudoPATH 与用户的相同? - Tom
1
@Rob:与此同时,我已经找到了一种方法(请参见下面的答案)。 - Tom
1
我喜欢你解释的方式!谢谢 :) - Kasparov92
1
我想知道为什么当我以sudo身份运行时,PATH变量的值与我的常规用户不同。我在/etc/environment中设置了PATH,但是在以sudo方式运行时并没有使用这个PATH。我应该在哪里设置sudo使用的PATH? - Philip Rego
显示剩余9条评论

168

我在这里看到的其他解决方案都基于某些系统定义,但实际上可以通过正确调用sudo(使用env命令)使其使用当前的PATH和/或其余环境(使用-E选项),只需执行以下操作:

sudo -E env "PATH=$PATH" <command> [arguments]

事实上,你可以用它来创建一个别名:

alias mysudo='sudo -E env "PATH=$PATH"'

你还可以将别名本身命名为sudo,替换原始的sudo


3
汉语翻译:我喜欢这个解决方案,汤姆,因为你有意识地使用了不同的sudo调用。无论采取何种方式(有很多种方式),时刻注意正在使用的PATH变量是很重要的。 - Rob Kielty
5
我认为这是Ubuntu发行版中“命令未找到”问题的正确和最标准化的解决方案。谢谢你。 - Omar Tariq
2
您可以将别名添加到您的./bashrc文件中,以便在会话之间保存它。 - George
1
我在使用mysudo后遇到了“权限被拒绝”的问题。 - Samuel Jenks
1
你没有解释它们为什么首先不同。 - Philip Rego
显示剩余3条评论

33

检查sudo的secure_path

[root@host ~]# sudo -V | grep 'Value to override'
Value to override user's $PATH with: /sbin:/bin:/usr/sbin:/usr/bin
如果$PATH被覆盖,请使用visudo编辑/etc/sudoers
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

谢谢!那帮助解决了sudo无法运行命令的谜团。 - Evgeny Goldin
你没有解释它们首先为什么不同。 - Philip Rego
@PhilipRego - 这些答案已经有6年的历史了,如果你觉得多个答案中缺乏足够的细节...试着提供一些关于你所寻找的内容的建议,或者更好的方法是编辑答案以提供你认为缺少的细节。 - codemonkee
在Ubuntu 20.04中,sudo -V | grep 'Value to override'的输出为空。 - Hem
我不使用Ubuntu @Hem。也许在查看sudo -V时输出不同,而且grep没有捕获相同的文本。无论如何,请查看Ubunto和Sudoers手册,了解如何应用secure_path和其他方面。- https://manpages.ubuntu.com/manpages/focal/man5/sudoers.5.html - codemonkee

8
  1. 检查您是否对脚本具有执行权限。即 chmod +x foo.sh
  2. 检查该脚本的第一行是否为#!/bin/sh或类似命令。
  3. 如果使用sudo,您可能在错误的目录中。请使用sudo pwd进行检查。

6

您还可以在超级用户的PATH路径下的一个目录(例如/usr/local/bin)中创建一个指向您的脚本的软链接。这样,sudo命令就可以使用它了。

chmod +x foo.sh
sudo ln -s path-to-foo.sh /usr/local/bin/foo

请看这个答案,了解应该将软链接放在哪个目录中。


2
尝试使用chmod u+x foo.sh而不是chmod +x foo.sh,如果您在上面的指南中遇到问题。当其他解决方案无法解决问题时,这对我有用。

2
似乎即使你明确给出文件路径,Linux也会显示“找不到命令”的提示。
[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
sudo: /tmp/uid.sh: command not found
1
[veeam@jsandbox ~]$ chmod +x /tmp/uid.sh
[veeam@jsandbox ~]$ sudo /tmp/uid.sh;echo $?
0

这是一个有些误导的错误,但从技术上讲也许是正确的。文件只有在可执行时才成为命令,因此无法找到它。


1

0

好的,这是我的解决方案: 只需在~/.bash_aliases中添加以下内容:

# ADDS MY PATH WHEN SET AS ROOT
if [ $(id -u) = "0" ]; then
   export PATH=$PATH:/home/your_user/bin 
fi

太棒了!现在你可以使用sudo或设置为ROOT来执行自己的脚本,而不需要每次都执行export PATH=$PATH:/home/your_user/bin。

请注意,由于超级用户的HOME为/root,因此我需要明确添加我的路径。


-1

如果您不太熟悉命令行并且正在使用Ubuntu,则可以按以下步骤解决问题:

  1. 打开包含文件的文件夹窗口
  2. 右键单击可执行文件,然后选择属性
  3. 转到权限选项卡,并突出显示允许将文件作为程序执行

enter image description here

使用这个解决方案,您可以允许用户将文件作为程序执行,而无需使用sudo(或更改根目录下的PATH环境变量)。

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