首先,我们只讨论 Debian/Ubuntu 操作系统。(如有冒犯请见谅,因为我只熟悉这两个)
第二,我们谈论的是仅具有 sudo 权限的非 root 用户。
每次我要以 sudo 权限运行命令时,我总是问自己应该使用sudo bash -c 'command'
还是只使用sudo command
,这对我来说有点痛苦。
并且由于有些情况sudo command
不能直接起作用,例如,
sudo echo "smth" >> /etc/privilegedfile
但它似乎总是通过使用sudo sh -c "echo 'smth' >> /etc/privilegedfile"
或sudo bash -c "echo 'smth' >> /etc/privilegedfile"
(或使用其他工具,比如tee
让它工作。)
所以问题是,
是否有任何场合(例外)sudo bash -c 'command'
不能执行,但只能执行sudo command
?
使用sudo bash -c
而不是sudo
永远使用是个好主意吗?
Ste*_*itt 11
sudo bash -c
和sudo
显着不同,因为sudo
可以配置为向运行特定命令的特定用户授予权限。因此,您可能会发现自己处于允许运行的设置中sudo command
(对于 的某些值command
),但不允许运行sudo bash
。
总的来说这是一个好主意,越具体越好,这样有利于sudo command
过sudo bash -c command
。
bash -c
与 sudo 一起使用可能比sudo
单独使用要危险得多。在 shell 上运行命令时,shell 会以各种方式处理和扩展许多特殊字符。例如rm *.txt
,正是您正在键入的 shell(通常是 bash)将 *.txt 扩展为当前文件夹中以 .txt 结尾的文件列表。sudo 命令出于对简单性和安全性的渴望,并没有这样做。相反,它只是直接使用您传递给它的参数直接运行命令。例如,假设您在 shell 中运行以下命令:
$ file=/etc/passwd
$ sudo vim $file
$ ls *.txt
hello.txt world.txt
$ sudo rm *.txt
Run Code Online (Sandbox Code Playgroud)
第一行设置一个变量,$file
在您当前的 shell 中,将 sudo 命令作为 运行sudo vim /etc/passwd
,然后列出并 sudo 删除所有文本文件。在 sudo 有机会看到或运行它之前,shell 扩展了该变量和文件名通配符。在最后一行,当 sudo 被调用时,它看到它正好被赋予了三个参数rm
,hello.txt
、 和world.txt
。然后它rm
以用户 root 的身份调用,仅使用两个参数,无需进一步处理。如果我在它周围使用引号,例如,,sudo rm "*.txt"
那么 sudo 将改为rm
使用一个参数查看并调用命令*.txt
. rm 命令会从字面上理解并尝试删除一个名为“*.txt”的文件,但发现它不存在。它甚至不会查看以 .txt 结尾的另外两个文件。该扩展是由外壳完成的。
只是为了说明这一点,当您取消 shell 为使生活更轻松所做的魔力时,我上面列出的命令必须直接编写,没有任何变量或通配符,如下所示:
$ sudo vim /etc/passwd
$ ls hello.txt world.txt
hello.txt world.txt
$ sudo rm hello.txt world.txt
Run Code Online (Sandbox Code Playgroud)
的无ls
,rm
和sudo
自己知道如何扩大* .txt或$file
,那就是shell的工作。现在,让我们看看bash -c
sudo中哪些地方可能存在危险。请不要在家里尝试:
$ file=/etc/passwd
$ sudo vim $file
# Take a short break from your computer here...
$ file="/lets/be/malicious; cp /dev/zero /dev/sda"
$ sudo vim $file # Might see a harmless error here
$ sudo bash -c "vim $file" # Goodbye hard-drive
Run Code Online (Sandbox Code Playgroud)
虽然我不得不承认,这是一个非常人为的例子,但我希望不难想象这里可能发生的一些潜在危险。问题是您现在让 shell 以 root 身份扩展元字符。假设您走开了,有人修改了文件变量以在其中嵌入恶意命令,该命令会擦除您的硬盘驱动器。使用之前的 语法sudo vim $file
,它将扩展为普通的非特权用户并失败。在第二个用法中,它将扩展 $file 和嵌入其中的所有魔法,以在以 root 身份运行的成熟 shell 中运行。