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

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

我的猜测如下:

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

su说:

su: must be run from a terminal

你会怎么办?

答案1

sudo支持这一点。

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

不同之处在于,它sudo要求您提供用户密码,而不是root(目标用户)密码。但是,如果您愿意,可以使用中的targetpw(orrunaspwrootpw) 指令更改此行为sudoers.conf


然而,阅读您想要执行的操作,虽然这解决了权限升级问题,但它不会达到您的预期。这意味着/output/file不会以 root 用户身份创建,而是以您的用户身份创建/修改。

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

但是,您可以使用tee它来执行此操作,因为该tee实用程序将自行打开文件。

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

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

你还可以这样做:

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

...这不太神秘。

答案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

相关内容