用一个 sudo 执行一行命令

rub*_*o77 22 bash command-history sudo

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

echo "something" > /path/foobar
Run Code Online (Sandbox Code Playgroud)

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

我试过

sudo echo "something" > /path/foobar
Run Code Online (Sandbox Code Playgroud)

但不起作用,因为须藤只计数的edit而不是右部
>

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

echo "something" | sudo tee /path/foobar
Run Code Online (Sandbox Code Playgroud)

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

sudo !!
Run Code Online (Sandbox Code Playgroud)

有没有办法“回收”最后一行,只sudo在前面添加?

Gil*_*il' 15

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

sudo bash -c !!
Run Code Online (Sandbox Code Playgroud)

除了这不太有效,因为!!插入了上一个命令的文本、特殊字符和所有内容。您需要将命令的文本作为字符串检索并将其作为参数传递给sh. 幸运的是,bash 的fc内置功能可以让您做到这一点¹。

sudo bash -c "$(fc -ln -1)"
Run Code Online (Sandbox Code Playgroud)

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

sudo "$BASH" -c "$(fc -ln -1)"
Run Code Online (Sandbox Code Playgroud)

请注意,由于该命令是在单独的 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)"
Run Code Online (Sandbox Code Playgroud)

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

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

sudo zsh -c $history[$[HISTCMD-1]]
Run Code Online (Sandbox Code Playgroud)

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

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


Boo*_*ogy 9

如果你想用sudo重做同样的命令!!执行如下命令后:

echo "something">/path/file
Run Code Online (Sandbox Code Playgroud)

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

!!:gs/>/|sudo tee -a /
Run Code Online (Sandbox Code Playgroud)

-a参数后使用空格。

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


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

echo "something" | sudo tee myfile
Run Code Online (Sandbox Code Playgroud)

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

如果要重复该命令并将文本附加到文件中,tee 命令具有用于附加的-a选项。所以你可以用

sudo !!
Run Code Online (Sandbox Code Playgroud)

文本将附加到文件中

例子:

echo "something" | sudo tee -a /path/file
sudo !!
Run Code Online (Sandbox Code Playgroud)