例如,如果我想创建一个文件并在一行中输入文本,我可以使用运算符将输出重定向到文件中>
:
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 要求将first
和last
数字传递给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 中的别名,但那也一样好。 fc
hist
答案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