使用sudo时找不到命令


145

foo.sh我的主文件夹中有一个脚本。

当我导航到该文件夹​​并输入时./foo.sh,我得到

-bash: ./foo.sh: Permission denied

当我使用时sudo ./foo.sh,我得到

sudo: foo.sh: command not found

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

Answers:


151

没有权限

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

为了完全了解Linux 文件权限,您可以研究chmod命令的文档。chmodchange mode的缩写,是用于更改文件的权限设置的命令。

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

ls -l foo.sh

...将列出文件所有者,组所有者以及不是文件所有者或文件所属组成员的其他所有人的READ,WRITE和EXECUTE权限(有时会引用最后一个权限组作为“世界”或“其他”)

这是有关如何解决您的情况下“ 拒绝权限”错误的摘要。

$ 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用户身份运行它。

根用户没有找到自己指令的原因,很可能是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

请注意,尽管类似,但在这种情况下,PATH中包含的目录(非特权用户(rkielty))和超级用户是不同的

其中目录foo.sh所在是不存在于根用户的PATH变量,因此命令没有发现错误。


1
@Nakilon,如果您在问题中提供详细信息,我应该能够为您进一步解决问题。问题可能是哪个外壳程序(您的第一个命令外壳程序或sudo启动的外壳程序)评估了$ PWD
Rob Kielty

6
@Rob:那么怎样才能实现sudoPATH一样的用户?
汤姆(Tom)

1
@Rob:在此期间我找到了一种方法(请参阅下面的答案)。
汤姆(Tom)

1
我喜欢你的解释方式!谢谢:)
Kasparov92 '97年

1
@Tom,您可以在/ etc / sudoers中更改secure_path
DennisLi '19

97

到目前为止,我在这里看到的其他解决方案都是基于一些系统定义的,但是实际上可以通过正确调用sudo当前PATH(使用env命令)和/或其余环境(使用-E选项)来使用:

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

实际上,可以使用别名:

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

(也可以使用别名本身来sudo代替原来的别名sudo。)


3
我喜欢这个解决方案,汤姆,因为您有意识地使用了不同的sudo调用。重要的是要始终注意设置的路径(并且有很多)使用什么PATH变量。
罗伯·基尔蒂

4
我相信这是command not foundUbuntu发行版所面临问题的正确且最标准化的解决方案。谢啦。
奥马尔·塔里克

您可以将别名添加到您的别名中以./bashrc在会话之间保存它
George

18

检查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 2014年

7
  1. 检查您是否对该脚本具有执行权限。即chmod +x foo.sh
  2. 检查该脚本的第一行是#!/bin/sh还是这样。
  3. 对于sudo,您在错误的目录中。与...核对sudo pwd

5

您还可以/usr/local/bin在超级用户PATH 的目录之一中创建到脚本的软链接(例如)。然后它将可用于sudo。

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

看一下这个答案,以了解将软链接放入哪个目录。


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

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

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

瞧!现在,您可以使用sudo执行自己的脚本或将其设置为ROOT,而不必每次都执行导出PATH = $ PATH:/ home / your_user / bin。

注意,添加路径时我需要明确,因为超级用户的HOME是/ root


1

尝试chmod u+x foo.sh,而不是chmod +x foo.sh如果你有以上的导游麻烦。当其他解决方案不起作用时,这对我有用。


1

上面有很好的答案。如果在尝试使用它们之后,仍然可以command not found使用整个文件路径再试一次:

sudo /home/user/path/to/foo.sh
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.