Betrachten Sie die beiden Befehle getrennt:
utility 2>&1 >output.log
Da hier Umleitungen von links nach rechts verarbeitet werden, wird der Standardfehlerstrom zuerst an die Stelle umgeleitet, an der sich der Standardausgabestream befindet (möglicherweise an die Konsole), und dann wird der Standardausgabestream in eine Datei umgeleitet. Der Standardfehlerstrom würde nicht in diese Datei umgeleitet.
Der sichtbare Effekt davon wäre, dass Sie das erhalten, was bei Standardfehlern auf dem Bildschirm erzeugt wird und was bei Standardausgaben in der Datei erzeugt wird.
utility 2>&1 | tee output.log
Hier leiten Sie Standardfehler an dieselbe Stelle um wie den Standardausgabestream. Dies bedeutet, dass beide Streams tee
als ein einziger vermischter Ausgabestream an das Dienstprogramm weitergeleitet werden und dass diese Standardausgabedaten in der angegebenen Datei von gespeichert werden tee
. Die Daten würden zusätzlich von tee
in der Konsole reproduziert (dies ist, was tee
es Datenströme dupliziert).
Welche davon verwendet wird, hängt davon ab, was Sie erreichen möchten.
Beachten Sie, dass Sie den Effekt der zweiten Pipeline nicht einfach reproduzieren können >
(wie in utility >output.log 2>&1
, wodurch sowohl die Standardausgabe als auch der Fehler in der Datei gespeichert werden). Sie müssten verwenden tee
, um die Daten sowohl in der Konsole als auch in der Ausgabedatei abzurufen.
Zusätzliche Bemerkungen:
Der sichtbare Effekt des ersten Befehls,
utility 2>&1 >output.log
wäre das gleiche wie
utility >output.log
Dh die Standardausgabe geht in die Datei und der Standardfehler geht in die Konsole.
Wenn am Ende jedes der obigen Befehle ein weiterer Verarbeitungsschritt hinzugefügt würde, würde dies jedoch einen großen Unterschied bedeuten:
utility 2>&1 >output.log | more_stuff
utility >output.log | more_stuff
In der ersten Pipeline wird more_stuff
der ursprüngliche Standardfehlerstrom utility
als Standardeingabedaten abgerufen, während in der zweiten Pipeline der more_stuff
Teil der Pipeline nichts erhält , da nur der resultierende Standardausgabestrom jemals über eine Pipe gesendet wird auf seiner Standardeingabe zu lesen.
utility 2>&1 | tee output.log
Wollen Sie mit dem Befehl " sagen, dass 1 an tee gerichtet ist, 2 auch. Da tee den Stream dupliziert, wird die Ausgabe sowohl auf der Konsole angezeigt als auch in eine Datei geschrieben? Daher der Unterschied zwischenutility 2>&1 > output.log
undutility 2>&1 | tee output.log
liegt daran,tee
dass es den Stream dupliziert. Wäre das richtig?utility 2>&1 > output.log | more_stuff
undutility >ouput.log
| more_stuff, is the difference that
more_stuff` hat die Standardfehlerausgabe an die Konsole als Eingabemore_stuff
? Da im zweiten Beispiel keine Ausgabe an die Konsole erfolgt, erfolgt im Wesentlichen keine Eingabe anmore_stuff
? Wenn ja, ist dies nicht klar, da Sie im vorhergehenden Absatz feststellen, dass die Standardausgabe in die Datei und der Standardfehler in die Konsole übertragen wird.more_stuff
Würde im ersten Befehl empfangen, wasutility
ursprünglich an seinen Fehlerstrom gesendet wurde (was aber zur Standardausgabe umgeleitet wurde). Nicht weil es auf der Konsole landen würde, wennmore_stuff
es nicht da wäre, sondern weil es zum Standardausgabestream geht .more_stuff
Empfängt im zweiten Befehl nichts, da auf der linken Seite der Pipeline keine Standardausgabe vorhanden ist. Der Fehlerstrom vonutility
würde im 2. Befehl immer noch auf der Konsole landen.utility > output.log | more_stuff
aus der Sicht eines Standardfehlers nicht zu einer Ausgabe im Standardausgabestream führt?Redaktioneller Hinweis
Bitte lesen Sie unbedingt die Kommentare zu dieser Antwort - derobert .
Ursprüngliche Antwort
2>&1 >output.log
Mittel beginnen zuerst alle Datei - Handle 2 stuff (Standardfehler) , um Datei - Handle 1 (Standardausgabe) sendet dann , dass die Datei sendenoutput.log
. Mit anderen Worten, senden Sie den Standardfehler und die Standardausgabe an die Protokolldatei.2>&1 | tee output.log
ist dasselbe mit dem2>&1
Bit, es kombiniert Standardausgabe und Standardfehler zu dem Standardausgabestrom. Dann leitet es dastee
Programm weiter, das seine Standardeingabe an seine Standardausgabe (wiecat
) und auch an die Datei sendet . Es kombiniert also die beiden Streams (Fehler und Ausgabe) und gibt diese dann an das Terminal und die Datei aus.Unterm Strich ist , dass die erste sendet
stderr
/stdout
in die Datei, während die zweite sendet sie an sowohl der Datei und die Standardausgabe (das ist wahrscheinlich das Terminal , wenn Sie in ein anderes Konstrukt sind die Standardausgabe umgeleitet wurde).Ich erwähne diese letzte Möglichkeit, weil Sie Dinge haben können wie:
wo nichts auf dem terminal landet.
quelle
cat /doesnotexist 2>&1 >output.txt
- Aufcat: /doesnotexist: No such file or directory
dem Terminal wird angezeigt, und output.txt ist eine leere Datei. Rangfolge und Schließung sind im Spiel:2>&1
(dup fd2 vom aktuellen fd1), dann>output.txt
(fd1 zur output.txt umleiten, nichts anderes ändern). Der Grund, der2>&1 |
anders ist, liegt in der Rangfolge:|
vor>
.Der erste Befehl erledigt die andere Aufgabe:
Nach
Das alte STDOUT wird in STDERR gespeichert (kopiert) und dann wird STDOUT in die Datei umgeleitet.
Also, stdout geht zur Datei und stderr geht zur Konsole.
Und in
Beide Streams werden auf tee umgeleitet. Tee dupliziert alle Eingaben in seine Standardausgabe (in Ihrem Fall in die Konsole) und in die Datei (
output.log
).Und es gibt eine andere Form von erstem:
Dadurch werden sowohl STDOUT als auch STDERR in die Datei umgeleitet.
quelle
Ersteres wird nur in die Datei ausgegeben. Die zweite Ausgabe erfolgt sowohl in der Datei als auch auf dem Bildschirm.
quelle
Der Grund dafür
2>&1 | tee
ist, dass sowohl stdout als auch stderr in einer Protokolldatei erfasst und gleichzeitig auf dem Bildschirm angezeigt werden können. Dies könnte auch geschehen>output.txt 2>&1 & tail -f
, aber Sie würden nicht wissen, wann der Befehl im Hintergrund beendet wurde - wird das Programm beendet oder wird es ohne Ausgabe ausgeführt? Das2>&1 | tee
war eine verbreitete Redewendung für Programmierer.quelle
Sehen wir uns zuerst einen Beispielcode an:
Vergleichen wir die Ergebnisse:
./helloerror
+ Datei: keine Nachricht; Konsole: Nachricht 1,2,3;
./helloerror >error.txt
+ Datei: Nachricht 1,2; Konsole: Nachricht 3;
./helloerror 2>&1 >error.txt
+ Datei: Nachricht 1,2; Konsole: Nachricht 3;
+ wie ./helloerror> error.txt
./helloerror >error.txt 2>&1
+ Datei: Nachricht 3,1,2; Konsole: keine Nachricht;
+ beachte, dass die Reihenfolge 3 zuerst ist, dann 1, dann 2
./helloerror | tee error.txt 2>&1
+ Datei: Nachricht 1,2; Konsole: Nachricht 3,1,2;
+ beachte, dass die Reihenfolge 3 zuerst ist, dann 1, dann 2
./helloerror 2>&1 | tee error.txt
+ Datei: Nachricht 3,1,2; Konsole: Nachricht 3,1,2;
Zu verwenden:
./helloerror >error.txt 2>&1
-> wenn man alle (stdout + stderr) Nachrichten in der Datei haben möchte, aber nicht auf der Konsole gedruckt
./helloerror 2>&1 | tee error.txt
-> wenn man alle Nachrichten (stdout + stderr) in einer Datei haben und auf der Konsole ausdrucken möchte
quelle
Hier ist ein Beitrag mit einer Zusammenfassung der Unix-Ausgabestreams: http://www.devcodenote.com/2015/04/unix-output-streams.html
Ein Ausschnitt aus der Post:
Es gibt 3 Standardausgabestreams:
quelle