In Bash anrufen foo
würde ein jede Ausgabe dieses Befehls auf dem stdout anzeigen.
Berufung foo > output
würde jede Ausgabe dieses Befehls in die angegebene Datei umleiten (in diesem Fall 'Ausgabe').
Gibt es eine Möglichkeit, die Ausgabe in eine Datei umzuleiten und auf stdout anzuzeigen?
foo > output
die Daten werden geschrieben stdout und stdout ist die Datei mit dem Namenoutput
. Das heißt, beim Schreiben in die Datei wird in stdout geschrieben. Sie fragen, ob es möglich ist, sowohl in stdout als auch in das Terminal zu schreiben.Antworten:
Der gewünschte Befehl heißt
tee
:Zum Beispiel, wenn Sie sich nur für stdout interessieren:
Wenn Sie stderr einschließen möchten, gehen Sie wie folgt vor:
2>&1
Leitet Kanal 2 (stderr / Standardfehler) in Kanal 1 (stdout / Standardausgang) um, sodass beide als stdout geschrieben werden. Es wird ab demtee
Befehl auch an die angegebene Ausgabedatei weitergeleitet .Wenn Sie an die Protokolldatei anhängen möchten, verwenden Sie außerdem Folgendes
tee -a
:quelle
-a
argument ontee
, um Inhalte anzuhängenoutput.file
, anstatt sie zu überschreiben:ls -lR / | tee -a output.file
$?
danach verwenden, wird der Statuscode von zurückgegebentee
, der wahrscheinlich nicht Ihren Wünschen entspricht. Stattdessen können Sie verwenden${PIPESTATUS[0]}
.2>&1
Dumps der Streams stderr und stdout.tee outfile
nimmt den Stream, den es bekommt und schreibt ihn auf den Bildschirm und in die Datei "outfile".Dies ist wahrscheinlich das, wonach die meisten Menschen suchen. Die wahrscheinliche Situation ist, dass ein Programm oder Skript lange Zeit hart arbeitet und viel Ausgabe produziert. Der Benutzer möchte es regelmäßig auf Fortschritt überprüfen, möchte aber auch, dass die Ausgabe in eine Datei geschrieben wird.
Das Problem (insbesondere beim Mischen von stdout- und stderr-Streams) besteht darin, dass die Streams vom Programm geleert werden. Wenn zum Beispiel alle Schreibvorgänge auf stdout sind nicht gespült, aber alle die Schreibvorgänge auf stderr sind , werden sie in der Ausgabedatei und auf dem Bildschirm in chronologischer Reihenfolge angezeigt.
Es ist auch schlecht, wenn das Programm nur alle paar Minuten 1 oder 2 Zeilen ausgibt, um den Fortschritt zu melden. In einem solchen Fall würde der Benutzer, wenn die Ausgabe nicht vom Programm geleert würde, stundenlang keine Ausgabe auf dem Bildschirm sehen, da nichts davon stundenlang durch das Rohr geschoben würde.
Update: Das Programm
unbuffer
, Teil desexpect
Pakets, löst das Pufferproblem. Dies führt dazu, dass stdout und stderr sofort auf den Bildschirm und die Datei schreiben und diese synchron halten, wenn sie kombiniert und umgeleitet werdentee
. Z.B:quelle
$ stdbuf -o 0 program [arguments...] 2>&1 | tee outfile
python
eine Option integriert ist-u
, die die Ausgabe entpuffert.Ein anderer Weg, der für mich funktioniert, ist:
wie im gnu bash Handbuch gezeigt
Beispiel:
Weitere Informationen finden Sie unter Umleitung
quelle
$?
danach verwenden, wird der Statuscode von zurückgegebentee
, der wahrscheinlich nicht Ihren Wünschen entspricht. Stattdessen können Sie verwenden${PIPESTATUS[0]}
.Sie können hauptsächlich die Zoredache- Lösung verwenden . Wenn Sie die Ausgabedatei jedoch nicht überschreiben möchten, sollten Sie das Tee mit der Option -a wie folgt schreiben:
quelle
Etwas hinzuzufügen ...
Der Paket-Entpuffer hat Support-Probleme mit einigen Paketen unter Fedora- und Redhat-Unix-Versionen.
Die Probleme beiseite legen
Das Folgende hat bei mir funktioniert
quelle
Verwenden
tail -f output
sollte funktionieren.quelle
Bonusantwort seit diesem Anwendungsfall hat mich hierher gebracht:
In dem Fall, in dem Sie dies als ein anderer Benutzer tun müssen
Beachten Sie, dass das Echo während Sie und das Schreiben der Datei als "some_user" ausgeführt werden. Dies funktioniert NICHT , wenn Sie das Echo als "some_user" ausführen und die Ausgabe mit >> "some_file" umleiten, da die Dateiumleitung erfolgt wie du.
Hinweis: tee unterstützt auch das Anhängen mit dem Flag -a. Wenn Sie eine Zeile in einer Datei als anderen Benutzer ersetzen müssen, können Sie sed als gewünschten Benutzer ausführen.
quelle
< command > |& tee filename
# Dadurch wird eine Datei "Dateiname" mit dem Befehlsstatus als Inhalt erstellt. Wenn eine Datei bereits vorhanden ist, wird vorhandener Inhalt entfernt und der Befehlsstatus geschrieben.< command > | tee >> filename
# Dadurch wird der Status an die Datei angehängt, der Befehlsstatus wird jedoch nicht auf standard_output (Bildschirm) gedruckt.Ich möchte etwas drucken, indem ich "Echo" auf dem Bildschirm verwende und diese Echo-Daten an eine Datei anhänge
quelle
Sie können dies für Ihr gesamtes Skript tun, indem Sie am Anfang Ihres Skripts Folgendes verwenden:
Diese Umleitung beide stderr und stdout gibt an die Datei mit dem Namen
mylogfile
und alles lassen geht an stdout zugleich .Es werden einige dumme Tricks verwendet:
exec
ohne Befehl, um Umleitungen einzurichten.tee
, um Ausgaben zu duplizieren,NUL
Zeichen, das durch die$'string'
spezielle Bash-Notation angegeben wird), um anzugeben, dass das Skript neu gestartet wird (von Ihrer ursprünglichen Arbeit darf kein gleichwertiger Parameter verwendet werden).pipefail
Option neu starten .Hässlich aber nützlich für mich in bestimmten Situationen.
quelle
Tee ist perfekt dafür, aber das wird auch den Job machen
quelle
;
, wird die Ausgabe während eines langsamen Befehls stark verzögert.