내 추측은 다음과 같습니다.
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
( runaspw
또는 ) 지시문을 사용하여 rootpw
이 동작을 변경할 수 있습니다 sudoers.conf
.
그러나 수행하려는 내용을 읽으면 권한 상승 문제가 해결되지만 예상한 대로 수행되지는 않습니다. 이는 /output/file
루트로 생성되지 않고 사용자로 생성/수정됨을 의미합니다 .
그 이유는 명령이 호출되기 전에 쉘 출력 리디렉션이 수행되기 때문입니다. 따라서 쉘이 열리고 /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'
...별로 신비롭진 않네요.
답변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