用一个 sudo 执行一行命令

用一个 sudo 执行一行命令

例如,如果我想创建一个文件并在一行中输入文本,我可以使用运算符将​​输出重定向到文件中>

echo "something" > /path/foobar

但如果我无权访问该文件夹/path/并且需要 sudo 权限,我如何才能像具有 sudo 权限的普通用户一样实现相同的命令?

我试过

sudo echo "something" > /path/foobar

但这是行不通的,因为 sudo 只edit计算
>

sudo su当然,我可以在使用或使用之前成为root tee

echo "something" | sudo tee /path/foobar

但我想找到一个解决方案,我可以通过以下方式使用最后一行作为替换

sudo !!

有没有办法“回收”最后一行并添加sudo到前面?

答案1

您不能只停留sudo在 shell 命令前面,您必须调用 shell 来再次评估该命令(执行诸如扩展变量、为重定向运算符打开文件等操作)。所以那是

sudo bash -c !!

只是这不太有效,因为!!插入了上一个命令的文本、特殊字符等等。您需要以字符串形式检索命令文本并将其作为参数传递给sh.幸运的是,bashfc内置让你做到这一点。

sudo bash -c "$(fc -ln -1)"

或者甚至,确保调用当前正在运行的相同版本的 bash:

sudo "$BASH" -c "$(fc -ln -1)"

请注意,由于该命令是在单独的 shell 进程中执行的,因此它继承环境变量(仅保留那些sudo,请注意),但不继承 shell 内部变量。 Shell 选项(例如kshglob)和其他设置也将从默认值开始。

相同的命令²适用于 zsh 和 ksh,但 ATT ksh93 要求将firstlast数字传递给fc³(也适用于 bash、zsh 和 pdksh/mksh):

sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"

$0仅当通过 $PATH 并且 $PATH 未更改或通过绝对路径调用 shell 时,用于指定正在运行的 shell 的可执行文件才有效。

这是 zsh 中的另一种方法,它稍微清晰一些,但更长:

sudo zsh -c $history[$[HISTCMD-1]]

最后的警告sudo是:针对潜在危险的命令。不要让它太容易使用它!

¹开头有一些额外的空格,命令替换会删除结尾处的换行符,但 shell 的语法并不关心这一点。
²我不认为 zsh 或 ksh 有像 bash 那样的东西$BASH$0仅当它是绝对路径或不包含斜杠且命令搜索路径未更改时才有效。
³是 ATT ksh 中的别名,但那也一样好。 fchist

答案2

如果你想重做相同的命令须藤!!执行如下命令后:

echo "something">/path/file

您可以使用全局替换语法来调用命令:

!!:gs/>/|sudo tee -a /

在后面使用一个空格-A范围。

这相当于须藤!!但可以帮助您绕过 < 和 > 的 sudo 限制。因为 sudo 不允许使用 [<, >]。


要绕过重定向的 sudo 限制,您可以像这样使用它:

echo "something" | sudo tee myfile

tee 命令将允许您从标准输入读取并写入标准输出和文件

如果您想重复该命令并将文本附加到文件中,则 tee 命令具有-A附加选项。所以你可以用以下命令回忆命令

sudo !!

并且文本将被附加到文件中

例子:

echo "something" | sudo tee -a /path/file
sudo !!

答案3

这似乎很简单sudo sh -c "!!"

$ cd /
$ echo hello > foo
bash: foo: Permission denied
$ sudo sh -c "!!"
sudo sh -c "echo hello > foo"
$ ls -l foo
-rw-r--r-- 1 root root 6 Jun 20 16:21 foo

相关内容