使用一个sudo执行一行命令


21

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

echo "something" > /path/foobar

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

我试过了

sudo echo "something" > /path/foobar

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

当然,我可以先成为root sudo su或使用tee

echo "something" | sudo tee /path/foobar

但我想找到一个解决方案,在其中我可以通过替换来处理最后一行

sudo !!

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



这不是重复项。我提取了真正的Qeustion并更改了标题。现在正是我真正想要的东西
rubo77 2014年

它肯定重复的,但现在有所不同。在我看来,您是根据Boogy的答案重写问题的,这很好-很好的答案。我撤回了我的亲密投票,但这仍然是不可避免的(人们通常会在问题临近时自动投票而不关注该问题):在@goldilocks关闭时发表评论,我将投票以重新开放。一旦发生这种情况,您也可以在聊天中辩护。
goldilocks 2014年

Answers:


13

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

sudo bash -c !!

但这不是很有效,因为它会!!插入上一个命令的文本,特殊字符以及所有字符。您需要以字符串形式检索命令文本,并将其作为参数传递给sh。幸运的是,bash的fc内置功能使您可以做到这一点¹。

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

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

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

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

尽管ATT ksh93要求将first和和last数字都传递给fc³(在bash,zsh和pdksh / mksh中也适用),但相同的命令²在zsh和ksh 中也可以使用:

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

$0仅当通过$ PATH调用外壳且$ PATH不变或通过绝对路径调用外壳时,使用来指定正在运行的外壳的可执行文件。

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

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

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

¹ 开头有一些额外的空格,命令替换在结尾处去除了换行符,但是shell的语法对此并不在乎。
² 我认为zsh或ksh没有bash的东西$BASH$0仅当它是绝对路径或不包含斜杠且命令搜索路径未更改时才起作用。
³ ATT ksh中的别名,但同样好。 fchist


9

如果要使用sudo重做相同的命令在执行如下命令后:

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 !!

不错的解决方案,但是有点难记。如何使用!!为命令创建别名?记得最后一条命令
rubo77 2014年

-a真正需要的?>将覆盖一个文件,tee -a将追加,它将是>>
rubo77 2014年

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

3
如果命令使用引号,则不一定是等效的。考虑echo "foo bar"哪个会变成sh -c "echo "foo bar""哪个会打印foo而不是foo bar
godlygeek 2014年

我尝试了sudo sh -c '!!'如果您的命令,但是也没有用
rubo77 2014年

然后,如果您的命令同时使用单引号和双引号怎么办?还是双引号和变量扩展?如果用户确实:a=b然后echo "$a" >file,然后sudo sh -c '!!'它会扩展到sudo sh -c 'echo $a >file'这将打印一个空行,而不是bfile
godlygeek 2014年

所以也许有某种更好的解决方案?
rubo77 2014年

1
我认为没有任何解决方案无需您修改命令即可在100%的时间内运行。使用sudo得到一个root shell,然后复制并粘贴命令到这将是最接近的,但如果命令预计将在您的非root的shell中设置的使用变量失败。sudo sh -c "!!"对于简单的命令而言,使用效果很好,但对于复杂的命令却充满了困惑。我认为最好的建议是不要期望有某个命令会100%地起作用-学习一些可能的解决方案并在最合适的时候应用它们。
godlygeek 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.