Meine Vermutung war wie folgt:
echo "Generating some text" | su - -c cat >/output/file
Aber su
sagt:
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 su
sagt:
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 sudo
nach 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 runaspw
oder 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/file
wird 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/file
und übergibt diese geöffnete Datei an su
/ sudo
(und folglich cat
).
Sie können tee
dies jedoch stattdessen verwenden, da das tee
Dienstprogramm die Datei selbst öffnet.
echo "hello world" | sudo tee /output/file >/dev/null
Grundsätzlich wird tee
die Ausgabe in /output/file
und 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 |pipe
Vorher, 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 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
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