我在我的主目录下有一个名为foo.sh
的脚本。
当我进入这个目录并输入./foo.sh
时,会出现
-bash: ./foo.sh: 权限被拒绝
。
当我使用sudo ./foo.sh
时,会出现
sudo: foo.sh: 找不到命令
。
为什么会发生这种情况,我该如何解决?
权限被拒绝
为了运行脚本,文件必须具有可执行权限位设置。
要完全理解Linux 文件权限,可以研究chmod
命令的文档。chmod是"改变模式"(change mode)的缩写,它用于更改文件的权限设置。
要阅读本地系统的chmod文档,请从命令行运行man chmod
或info 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 中的目录 不相同。foo.sh
所在的目录,因此会出现 命令未找到 的错误。我在这里看到的其他解决方案都基于某些系统定义,但实际上可以通过正确调用sudo
(使用env
命令)使其使用当前的PATH
和/或其余环境(使用-E
选项),只需执行以下操作:
sudo -E env "PATH=$PATH" <command> [arguments]
事实上,你可以用它来创建一个别名:
alias mysudo='sudo -E env "PATH=$PATH"'
你还可以将别名本身命名为sudo
,替换原始的sudo
。
./bashrc
文件中,以便在会话之间保存它。 - George检查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 -V
时输出不同,而且grep
没有捕获相同的文本。无论如何,请查看Ubunto和Sudoers手册,了解如何应用secure_path
和其他方面。- https://manpages.ubuntu.com/manpages/focal/man5/sudoers.5.html - codemonkeechmod +x foo.sh
#!/bin/sh
或类似命令。sudo pwd
进行检查。您还可以在超级用户的PATH路径下的一个目录(例如/usr/local/bin
)中创建一个指向您的脚本的软链接。这样,sudo命令就可以使用它了。
chmod +x foo.sh
sudo ln -s path-to-foo.sh /usr/local/bin/foo
请看这个答案,了解应该将软链接放在哪个目录中。
chmod u+x foo.sh
而不是chmod +x foo.sh
,如果您在上面的指南中遇到问题。当其他解决方案无法解决问题时,这对我有用。[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
这是一个有些误导的错误,但从技术上讲也许是正确的。文件只有在可执行时才成为命令,因此无法找到它。
在使用sudo时出现“命令未找到”的情况,一种更少hackier的方法是编辑secure_path。
这里有一个完美的描述: https://superuser.com/questions/927512/how-to-set-path-for-sudo-commands
好的,这是我的解决方案: 只需在~/.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,因此我需要明确添加我的路径。
sudo
的PATH
与用户的相同? - Tom/etc/environment
中设置了PATH,但是在以sudo方式运行时并没有使用这个PATH。我应该在哪里设置sudo使用的PATH? - Philip Rego