使用sudo时找不到命令

Nek*_*eko 127 linux bash sudo

foo.sh在我的主文件夹中调用了一个脚本.

当我导航到这个文件夹,然后输入时./foo.sh,我得到了

-bash: ./foo.sh: Permission denied.

当我使用时sudo ./foo.sh,我明白了

sudo: foo.sh: command not found.

为什么会发生这种情况以及如何解决?

Rob*_*lty 136

没有权限

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

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

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

ls -l foo.sh
Run Code Online (Sandbox Code Playgroud)

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

以下是如何解决您的案例中的Permission Denied错误的摘要.

$ 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 
Run Code Online (Sandbox Code Playgroud)

所有者具有读写访问权限,但是 - 表示缺少可执行权限

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
   ^  ^  ^
Run Code Online (Sandbox Code Playgroud)

就Linux而言,foo.sh现在是可执行的.

使用sudo会导致找不到Command

使用sudo运行命令时,您实际上是以超级用户或root身份运行它.

根用户没有找到自己指令的原因,很可能是PATH根环境变量不包括地方目录foo.sh所在.因此找不到命令.

PATH环境变量包含搜索命令的目录列表.每个用户根据需要设置自己的PATH变量.查看设置运行的内容

env | grep ^PATH
Run Code Online (Sandbox Code Playgroud)

以下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
Run Code Online (Sandbox Code Playgroud)

请注意,虽然类似,但在这种情况下,PATH中包含的目录,非特权用户(rkielty)和超级用户不一样.

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

  • @Rob:那么如何使`sudo`的'PATH`与用户相同? (5认同)

Tom*_*Tom 80

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

sudo -E env "PATH=$PATH" <command> [arguments]
Run Code Online (Sandbox Code Playgroud)

事实上,人们可以用它来制造别名:

alias mysudo='sudo -E env "PATH=$PATH"'
Run Code Online (Sandbox Code Playgroud)

(也可以命名别名sudo,替换原来的sudo.)

  • 我喜欢这个解决方案,汤姆,因为你有意识地使用不同的sudo调用.重要的是要注意PATH变量在任何时候都在使用,无论它设置的方式(并且有很多)都是如此. (3认同)
  • 我相信这是Ubuntu发行版面临的"未找到命令"问题的正确和最标准化的解决方案.谢啦. (3认同)
  • 您可以将别名添加到“./bashrc”以在会话之间保存它 (2认同)

cod*_*kee 15

检查sudo上的secure_path

[root@host ~]# sudo -V | grep 'Value to override'
Value to override user's $PATH with: /sbin:/bin:/usr/sbin:/usr/bin
Run Code Online (Sandbox Code Playgroud)

如果$PATH被覆盖则使用visudo和编辑/etc/sudoers

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
Run Code Online (Sandbox Code Playgroud)


Ed *_*eal 7

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


Tri*_*ima 5

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

chmod +x foo.sh
sudo ln -s path-to-foo.sh /usr/local/bin/foo
Run Code Online (Sandbox Code Playgroud)

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