Come posso elevare i privilegi nel mezzo della pipeline?


8

La mia ipotesi era la seguente:

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

Ma sudice:

su: must be run from a terminal

Cosa faresti?


Se hai trovato una soluzione, aggiungila come risposta di seguito.
Braiam,

@Braiam La soluzione non merita di essere una risposta.
x-yuri,

Risposte:


8

sudo supporta questo.

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

La differenza è che sudorichiede la password dell'utente, non la password root(utente di destinazione). Tuttavia, se lo desideri, puoi modificare questo comportamento con la direttiva targetpw(o runaspwo 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/filenon 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/filee quindi passa quel file aperto a su/ sudo(e, di conseguenza, cat).

Tuttavia è possibile utilizzare teeper fare questo invece, poiché l' teeutilità aprirà il file stesso.

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

Fondamentalmente teecopia l'output in /output/filee STDOUT, tuttavia STDOUT viene reindirizzato in /dev/null.

Puoi anche fare:

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

... che è meno criptico.


È inoltre possibile "memorizzare nella cache" privilegi elevati invocando sudo -v. Ti chiederà la password se non usi Sudo da pochi minuti.
Winny,

2

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 |pipeprima di fare qualsiasi cosa, purché leggano il |pipetutto. 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 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

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

Lo so. Questo ha poco o niente a che fare con la domanda, o almeno così penso. Ma in qualche modo mi ha portato a una risposta :) Vedi la mia domanda aggiornata.
x-yuri,

@ x-yuri È ancora possibile inserire un documento qui nel mezzo di una pipeline. fare eco a qualcosa | {su 'do some stuff> /record.here'; } << QUI | fine eco del tubo \ n $ (gatto) \ n QUI \ n
mikeserv

In effetti, non ho pensato di usare cat all'interno di questo documento. Comunque, non hai bisogno di raggrupparti lì.
x-yuri,

@ x-yuri - dipende da cosa vuoi farci. Puoi usare uno o entrambi. Stavo solo cercando di dimostrare che avevi delle opzioni. La risposta di Patrick è quella corretta qui, questo è solo un altro modo più contorto. Quel documento qui raggruppa, tuttavia, raggruppa cat in una subshell.
Mikeserv,

Per raggruppamento intendevo parentesi graffe .
x-yuri,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.