파이프라인 중간에 권한을 어떻게 승격하나요?

파이프라인 중간에 권한을 어떻게 승격하나요?

내 추측은 다음과 같습니다.

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가 아닌 사용자의 비밀번호를 제공해야 한다는 것입니다. 그러나 원하는 경우 roottargetpw( runaspw또는 ) 지시문을 사용하여 rootpw이 동작을 변경할 수 있습니다 sudoers.conf.


그러나 수행하려는 내용을 읽으면 권한 상승 문제가 해결되지만 예상한 대로 수행되지는 않습니다. 이는 /output/file루트로 생성되지 않고 사용자로 생성/수정됨을 의미합니다 .

그 이유는 명령이 호출되기 전에 쉘 출력 리디렉션이 수행되기 때문입니다. 따라서 쉘이 열리고 /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를 사용하면 두 가지 가 모두 필요하지 않습니다 cat.

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

관련 정보