如何在管道中间提升特权?


8

我的猜测如下:

echo "Generating some text" | su - -c cat >/output/file

但是su说:

su: must be run from a terminal

你会怎么做?


如果您自己找到了解决方案,请在下面将其添加为答案。
Braiam 2014年

@Braiam该解决方案不应该是一个答案。
x-yuri

Answers:


8

sudo 支持这一点。

$ echo hello world | sudo cat  
SUDO password: 
hello world

所不同的是sudo要求您输入用户密码,而不是root(目标用户)密码。但是,如果您愿意,可以使用中的targetpwrunaspwrootpw)指令更改此行为sudoers.conf


但是,在阅读您要执行的操作时,虽然可以解决权限提升问题,但不会执行您期望的操作。含义/output/file将不会以root用户身份创建,而是会以您的用户身份创建/修改。

原因是在调用任何命令之前已完成外壳输出重定向。因此,外壳程序将打开/output/file,然后将打开的文件传递给su/ sudo(因此,是cat)。

但是,您可以改用tee此方法,因为该tee实用程序将自行打开文件。

echo "hello world" | sudo tee /output/file >/dev/null

基本上tee将输出复制到/output/file和STDOUT中,但是将STDOUT重定向到中/dev/null

您也可以这样做:

echo "hello world" | sudo sh -c 'cat > /output/file'

...这不太神秘。


您也可以通过调用“缓存”提升的特权sudo -v。如果您在几分钟内没有使用sudo,它将询问您的密码。
Winny

2

请注意,您不限于每个命令|pipe

this happens | then this | { then ; all of ; this too ; } | before this

所有这些进程都在同一时间被调用-但是它们都|pipe在实际执行任何操作之前先等待它们-只要它们完全读取了|pipe。因此,如果您需要评估可变的中间数据流或设置重定向,则可以。慢慢来。

echo "it takes time" |
{ exec 4>|file ; cat >&4 ; } |
( sleep 1 && cat <file )

it takes time

这是另一种方式:

echo "more of the same" |
( IFS= ; su -mc 'echo '"$(printf "'%s' " "`cat`")"' >|file' </dev/tty ) |
echo end of pipe

如果您不这样做,( subshell )该命令$(cat)也将得到</dev/tty

但是,如果您使用的是here-doc,则不需要两个cats:

rm ./file
su -c 'cat <&3 >|./file; echo "middle here"' 3<<HERE >&2 | {\
    until [ -s ./file ] ; do sleep 1 ; done ;\
    sed 's/beginning/end/' ./file ; }
$(echo "this is the beginning" | sed 'a\of the pipeline' | tee /dev/stderr)
HERE

输出:

this is the beginning
of the pipeline
Password:
middle here
this is the end
of the pipeline

以上大部分内容只是为了演示。您真正需要的是:

su -c 'cat <&3 >./file' 3<<HERE | { wait as needed ; more stuff to do ; }
$(echo "something" | and other things)
HERE

我知道。我认为这与这个问题几乎没有关系。但是不知何故,我找到了答案:)请参阅我的最新问题。
x-yuri 2014年

@ x-yuri您仍然可以在管道中间放置一个here-document。回声 {su'做一些事情> /record.here'; } <<这里| 回声管端\ n $(cat)\ nHERE \ n
mikeserv

确实,我没有想到在此文档中使用cat。无论如何,您不需要在那里分组。
x-yuri 2014年

@ x-yuri-取决于您要处理的内容。您可以使用其中之一。我只是想证明你有选择。帕特里克的答案在这里是正确的,这只是另一种更复杂的方法。尽管如此,here-doc确实可以分组-它将cat分组在一个子外壳中。
mikeserv 2014年

分组是指大括号
x-yuri 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.