知道哪些命令在 sudo 中中断的经验法则?

3 command-line sudo

有一些命令,如cdll那样,如果我将它们作为 运行sudo,它们的执行就会“中断”。

sudo命令在它们之前时,知道哪些命令会以这种方式“中断”的经验法则是什么?

这些数据可以帮助我和其他新手编写更稳定的脚本。

Ant*_*gan 6

只能运行外部命令sudo

须藤

sudo程序派生(启动)一个新进程以启动具有超级用户(或其他用户,如果使用该-u选项)的有效权限的外部命令。这意味着不能指定 shell 内部的命令;这包括 shell 关键字、内置函数、别名和函数。

确定命令是否可用作外部命令(而不是 shell 内部)的最佳方法是运行type -a command_name它,该命令显示包含指定可执行文件的所有位置。

示例 1:Shell 内置

在这种情况下,该cd命令仅可用作 shell 内置命令:

$ type -a cd
cd is a shell builtin
Run Code Online (Sandbox Code Playgroud)

当您尝试使用以下命令运行它时失败sudo

$ sudo cd /
sudo: cd: command not found
Run Code Online (Sandbox Code Playgroud)

示例 2:别名

在这种情况下,ls命令是外部的——但在用户的 shell 中也创建了一个同名的别名。

$ type -a ls
ls is aliased to `ls -F --color'
ls is /bin/ls
Run Code Online (Sandbox Code Playgroud)

如果我要运行sudo ls,它不会是作为超级用户运行的别名;如果我想要该-F选项,则必须将其明确包含为选项,即sudo ls -F.

示例 3:Shell 内置和外部命令

在这种情况下,该pwd命令同时作为 shell 内置命令和外部命令提供:

$ type -a pwd
pwd is a shell builtin
pwd is /bin/pwd
Run Code Online (Sandbox Code Playgroud)

在这种情况下,外部/bin/pwd命令将运行sudo

$ sudo pwd
/home/anthony
Run Code Online (Sandbox Code Playgroud)

通常作为 shell 内置命令和外部命令提供的命令的其他示例是 kill, test( [) 和echo.

使用 sudo 运行内部 shell 命令

如果您真的想以超级用户权限运行内置的 shell,则必须启动一个 shell 作为外部命令。例如,以下命令bash以超级用户身份运行,cd内置命令作为命令行选项提供:

$ sudo bash -c "cd /; ls"
bin   etc   lib  media  mnt  ntp.peers  proc  sbin     share  sys
tmp  var boot  dev  home  lost+found  misc   net  opt … …
Run Code Online (Sandbox Code Playgroud)

注意:别名不能作为命令传递给 Bash 使用它的-c选项。

外壳重定向

另一个需要注意的问题是 shell 重定向发生在当前 shell 的上下文中。如果我尝试运行sudo /bin/echo abc > /test.file,它将不起作用。我明白了-bash: /test.file: Permission denied。虽然 echo 命令以超级用户权限运行,但它会将其输出打印到我当前的(非特权)shell,并且作为普通用户,我没有写入/目录的权限。

一种解决方法是使用sudo启动一个新的 shell(类似于上面的示例):

sudo bash -c "echo abc > /test.file"
Run Code Online (Sandbox Code Playgroud)

在这种情况下,输出重定向发生在特权 shell(它有写入权限/)的上下文中。

另一种解决方案是以tee超级用户身份运行命令:

echo abc | sudo tee /test.file
Run Code Online (Sandbox Code Playgroud)