La mia ipotesi era la seguente:
echo "Generating some text" | su - -c cat >/output/file
Ma su
dice:
su: must be run from a terminal
Cosa faresti?
La mia ipotesi era la seguente:
echo "Generating some text" | su - -c cat >/output/file
Ma su
dice:
su: must be run from a terminal
Cosa faresti?
Risposte:
sudo
supporta questo.
$ echo hello world | sudo cat
SUDO password:
hello world
La differenza è che sudo
richiede la password dell'utente, non la password root
(utente di destinazione). Tuttavia, se lo desideri, puoi modificare questo comportamento con la direttiva targetpw
(o runaspw
o rootpw
) in sudoers.conf
.
Tuttavia, leggendo cosa stai cercando di fare, mentre questo risolve il problema di escalation dei permessi, non farà ciò che ti aspetti. Il significato /output/file
non verrà creato come utente root, verrà creato / modificato come utente.
Il motivo è che il reindirizzamento dell'output della shell viene eseguito prima di invocare qualsiasi comando. Quindi la shell si apre /output/file
e quindi passa quel file aperto a su
/ sudo
(e, di conseguenza, cat
).
Tuttavia è possibile utilizzare tee
per fare questo invece, poiché l' tee
utilità aprirà il file stesso.
echo "hello world" | sudo tee /output/file >/dev/null
Fondamentalmente tee
copia l'output in /output/file
e STDOUT, tuttavia STDOUT viene reindirizzato in /dev/null
.
Puoi anche fare:
echo "hello world" | sudo sh -c 'cat > /output/file'
... che è meno criptico.
sudo -v
. Ti chiederà la password se non usi Sudo da pochi minuti.
Solo così sai - non sei limitato a un singolo comando per |pipe
:
this happens | then this | { then ; all of ; this too ; } | before this
Tutti questi processi vengono invocati contemporaneamente, ma tutti attendono |pipe
prima di fare qualsiasi cosa, purché leggano il |pipe
tutto. Pertanto, se è necessario valutare un midstream variabile o impostare un reindirizzamento, è possibile. Prenditi il tuo tempo.
echo "it takes time" |
{ exec 4>|file ; cat >&4 ; } |
( sleep 1 && cat <file )
it takes time
Ecco un altro modo:
echo "more of the same" |
( IFS= ; su -mc 'echo '"$(printf "'%s' " "`cat`")"' >|file' </dev/tty ) |
echo end of pipe
Altrimenti anche ( subshell )
il comando $(cat)
otterrà </dev/tty
.
Ma se stai usando un documento qui, non hai bisogno di due cat
s:
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
PRODUZIONE:
this is the beginning
of the pipeline
Password:
middle here
this is the end
of the pipeline
La maggior parte di quanto sopra è solo per dimostrarlo. Tutto ciò di cui hai veramente bisogno è:
su -c 'cat <&3 >./file' 3<<HERE | { wait as needed ; more stuff to do ; }
$(echo "something" | and other things)
HERE