Meine Vermutung war wie folgt:
echo "Generating some text" | su - -c cat >/output/file
Aber susagt:
su: must be run from a terminal
Was würden Sie tun?
Meine Vermutung war wie folgt:
echo "Generating some text" | su - -c cat >/output/file
Aber susagt:
su: must be run from a terminal
Was würden Sie tun?
Antworten:
sudo unterstützt dies.
$ echo hello world | sudo cat
SUDO password:
hello world
Der Unterschied besteht darin, dass Sie sudonach Ihrem Benutzerpasswort gefragt werden, nicht nach dem root(Zielbenutzer-) Passwort. Wenn Sie dies wünschen, können Sie dieses Verhalten mit der Anweisung targetpw(oder runaspwoder rootpw) in ändern sudoers.conf.
Wenn Sie jedoch lesen, was Sie tun möchten, wird das Problem der Eskalation von Berechtigungen zwar gelöst, es wird jedoch nicht das tun, was Sie erwarten. Die Bedeutung /output/filewird nicht als Root-Benutzer erstellt, sondern als Ihr Benutzer erstellt / geändert.
Der Grund dafür ist, dass die Umleitung der Shell-Ausgabe erfolgt, bevor Befehle aufgerufen werden. Die Shell öffnet sich also /output/fileund übergibt diese geöffnete Datei an su/ sudo(und folglich cat).
Sie können teedies jedoch stattdessen verwenden, da das teeDienstprogramm die Datei selbst öffnet.
echo "hello world" | sudo tee /output/file >/dev/null
Grundsätzlich wird teedie Ausgabe in /output/fileund STDOUT kopiert, STDOUT wird jedoch in umgeleitet /dev/null.
Sie könnten auch tun:
echo "hello world" | sudo sh -c 'cat > /output/file'
... was weniger kryptisch ist.
sudo -v. Sie werden nach Ihrem Passwort gefragt, wenn Sie sudo seit einigen Minuten nicht mehr verwendet haben.
Nur damit Sie wissen - Sie sind nicht auf einen einzigen Befehl beschränkt |pipe:
this happens | then this | { then ; all of ; this too ; } | before this
Alle diese Prozesse werden gleichzeitig aufgerufen - aber sie warten alle auf das |pipeVorher, bevor sie tatsächlich etwas tun -, solange sie das |pipeüberhaupt lesen . Wenn Sie also eine Variable im Midstream auswerten oder eine Umleitung einrichten müssen, können Sie dies tun. Nimm dir die Zeit, die du brauchst.
echo "it takes time" |
{ exec 4>|file ; cat >&4 ; } |
( sleep 1 && cat <file )
it takes time
Hier ist ein anderer Weg:
echo "more of the same" |
( IFS= ; su -mc 'echo '"$(printf "'%s' " "`cat`")"' >|file' </dev/tty ) |
echo end of pipe
Wenn Sie dies nicht tun, wird ( subshell )der Befehl $(cat)ebenfalls angezeigt </dev/tty.
Wenn Sie jedoch ein Here-Doc verwenden, benötigen Sie keine zwei 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
AUSGABE:
this is the beginning
of the pipeline
Password:
middle here
this is the end
of the pipeline
Das meiste davon dient nur dazu, dies zu demonstrieren. Alles was Sie wirklich brauchen ist:
su -c 'cat <&3 >./file' 3<<HERE | { wait as needed ; more stuff to do ; }
$(echo "something" | and other things)
HERE