Wenn ich in einer Unix-Shell zur weiteren Bearbeitung kombinieren stderr
und stdout
in den stdout
Stream einbinden möchte , kann ich am Ende meines Befehls Folgendes anhängen:
2>&1
Wenn ich also head
die Ausgabe von g++
verwenden möchte, kann ich Folgendes tun:
g++ lots_of_errors 2>&1 | head
so kann ich nur die ersten fehler sehen.
Ich habe immer Probleme, mich daran zu erinnern, und ich muss ständig nachschlagen, und das liegt hauptsächlich daran, dass ich die Syntax dieses bestimmten Tricks nicht vollständig verstehe.
Kann jemand dies auflösen und Charakter für Charakter erklären, was 2>&1
bedeutet?
2>&1
als 2> / dev / null ;-)|&
eine Abkürzung ist,2>&1 |
wenn Sie zsh verwenden. Ich kann nicht darüber sprechen, ob dies für andere bourneähnliche Muscheln gilt oder ob es sich nur um eine zsh-Funktion handelt.Antworten:
Dateideskriptor 1 ist die Standardausgabe (
stdout
).Dateideskriptor 2 ist der Standardfehler (
stderr
).Hier ist ein Weg , um dieses Konstrukt zu erinnern (obwohl es nicht ganz korrekt ist): zuerst,
2>1
wie ein guter Weg aussehen kann umleitenstderr
zustdout
. Es wird jedoch tatsächlich als "Umleitungstderr
zu einer Datei mit dem Namen1
" interpretiert .&
gibt an, dass das Folgende ein Dateideskriptor und kein Dateiname ist. So wird das Konstrukt :2>&1
.quelle
&2>&1
?&
wird nur im Zusammenhang mit Umleitungen als "Dateideskriptor" interpretiert. Das Schreibencommand &2>&
wird analysiert alscommand &
und2>&1
, dh "command
im Hintergrund ausführen, dann den Befehl ausführen2
und seine Standardausgabe in seine Standardausgabe umleiten".2>'&1'
leitet stdout an weiter
afile.txt
. Dies ist das gleiche wie zu tunUm stderr umzuleiten, gehen Sie wie folgt vor:
>&
ist die Syntax zum Umleiten eines Streams zu einem anderen Dateideskriptor - 0 ist stdin, 1 ist stdout und 2 ist stderr.Sie können stdout zu stderr umleiten, indem Sie Folgendes tun:
Oder umgekehrt:
Kurz gesagt ...
2>
leitet stderr an eine (nicht angegebene) Datei weiter und&1
leitet stderr an stdout weiter.quelle
java ... 2&1 >> data.log
? Ich habe gesehen, dass einer meiner Kollegen dies getan hat.cmd 2>&1 >> somefile.log
wird stdout / stderr an eine Datei anhängen - es ist im Grunde das gleiche wie oben, mit>> file
anhängencmd 2>&1 >>file
leitet stderr nicht in die Datei um,cmd >> file 2>&1
tut es aber . Ordnung ist wichtig. Im ersten Fall wird stderr zum stdout der Shell umgeleitet (möglicherweise ein tty, wenn der Befehl interaktiv eingegeben wird), und dann wird stdout an die Datei weitergeleitet. Im zweiten Fall wird stdout an die Datei und dann stderr an dieselbe Stelle geleitet.0(or 1,2)>&0(or 1,2)
wie eine Option, um die Ausgabe zu steuern? Ist dasecho test >test.log 2>&1
gleiche wieecho test 2>&1 >test.log
?Einige Tricks zur Umleitung
Einige Syntax-Besonderheiten hierzu können wichtige Verhaltensweisen aufweisen. Es gibt einige kleine Proben über Umleitungen,
STDERR
,STDOUT
und Argumente Ordnung .1 - Überschreiben oder Anhängen?
Symbol
>
bedeutet Umleitung .>
bedeuten , an eine vollständige Datei senden und das Ziel überschreiben, falls vorhanden (siehenoclobber
Bash-Funktion auf # 3 später).>>
meine senden zusätzlich zu würde an Ziel anhängen, wenn vorhanden.In jedem Fall würde die Datei erstellt, wenn sie nicht vorhanden wäre.
2 - Die Shell-Befehlszeile ist auftragsabhängig !!
Um dies zu testen, benötigen wir einen einfachen Befehl, der an beide Ausgänge etwas sendet :
(Vorausgesetzt, Sie haben kein Verzeichnis mit dem Namen
/tnt
natürlich ;). Nun, wir haben es !!Also mal sehen:
Die letzte Befehlszeile wird
STDERR
auf der Konsole ausgegeben, und es scheint nicht das erwartete Verhalten zu sein ... Aber ...Wenn Sie eine Nachfilterung für eine Ausgabe, die andere oder beide durchführen möchten :
Beachten Sie, dass die letzte Befehlszeile in diesem Absatz genau die gleiche ist wie im vorherigen Absatz, in dem ich geschrieben habe , dass sie nicht das erwartete Verhalten zu sein scheint (dies könnte also sogar ein erwartetes Verhalten sein).
Nun, es gibt ein paar Tricks zu Umleitungen, um an beiden Ausgängen unterschiedliche Operationen durchzuführen :
Nota:
&9
Deskriptor würde wegen spontan auftreten) 9>&2
.Nachtrag: nota! Mit der neuen Version vonBash(
>4.0
) Es gibt eine neue Funktion und eine sexy Syntax für diese Art von Dingen:Und schließlich für eine solche kaskadierende Ausgabeformatierung:
Nachtrag: nota! Gleiche neue Syntax in beiden Richtungen:
Wenn
STDOUT
Sie einen bestimmten Filter durchlaufen, gehen Sie zu einemSTDERR
anderen und schließlich führen beide zusammengeführten Ausgänge einen dritten Befehlsfilter durch.3 - Ein Wort zu
noclobber
Option und>|
SyntaxHier geht es ums Überschreiben :
Während
set -o noclobber
anweisen bash nicht eine vorhandene Datei zu überschreiben, die>|
Syntax können Sie durch diese Einschränkung passieren:Die Datei wird jetzt jedes Mal überschrieben:
Durchgehen mit
>|
:Deaktivieren Sie diese Option und / oder fragen Sie nach, falls bereits festgelegt.
4 - Letzter Trick und mehr ...
Um beide Ausgaben von einem bestimmten Befehl umzuleiten , sehen wir, dass eine richtige Syntax sein könnte:
Für diesen speziellen Fall gibt es eine Verknüpfungssyntax:
&>
... oder>&
Hinweis: Wenn
2>&1
vorhanden,1>&2
ist auch eine korrekte Syntax:4b- Nun werde ich Sie überlegen lassen:
4c- Wenn Sie an weiteren Informationen interessiert sind
Sie können das feine Handbuch lesen, indem Sie auf Folgendes klicken:
in einem Bash Konsole ;-)
quelle
Ich habe diesen brillanten Beitrag zur Weiterleitung gefunden: Alles über Weiterleitungen
Leiten Sie sowohl die Standardausgabe als auch den Standardfehler in eine Datei um
Dieser Einzeiler verwendet den
&>
Operator, um beide Ausgabestreams - stdout und stderr - vom Befehl in die Datei umzuleiten. Dies ist die Verknüpfung von Bash, mit der beide Streams schnell zum selben Ziel umgeleitet werden können.So sieht die Dateideskriptortabelle aus, nachdem Bash beide Streams umgeleitet hat:
Wie Sie sehen können, zeigen sowohl stdout als auch stderr jetzt auf
file
. Alles, was an stdout und stderr geschrieben wurde, wird an geschriebenfile
.Es gibt verschiedene Möglichkeiten, beide Streams zum selben Ziel umzuleiten. Sie können jeden Stream nacheinander umleiten:
Dies ist eine weitaus häufigere Methode, um beide Streams in eine Datei umzuleiten. Zuerst wird stdout in die Datei umgeleitet, und dann wird stderr so dupliziert, dass es mit stdout identisch ist. Beide Streams zeigen also auf
file
.Wenn Bash mehrere Umleitungen sieht, werden diese von links nach rechts verarbeitet. Lassen Sie uns die Schritte durchgehen und sehen, wie das passiert. Bevor Sie Befehle ausführen, sieht die Dateideskriptortabelle von Bash folgendermaßen aus:
Jetzt verarbeitet Bash die erste Umleitungsdatei. Wir haben dies schon einmal gesehen und es macht stdout auf die Datei zu verweisen:
Als nächstes sieht Bash die zweite Umleitung 2> & 1. Wir haben diese Umleitung noch nie gesehen. Dieser dupliziert den Dateideskriptor 2, um eine Kopie des Dateideskriptors 1 zu sein, und wir erhalten:
Beide Streams wurden in eine Datei umgeleitet.
Seien Sie hier jedoch vorsichtig! Schreiben
ist nicht dasselbe wie schreiben:
Die Reihenfolge der Weiterleitungen ist in Bash wichtig! Dieser Befehl leitet nur die Standardausgabe in die Datei um. Der stderr druckt weiterhin auf dem Terminal. Um zu verstehen, warum dies geschieht, gehen wir die Schritte noch einmal durch. Bevor Sie den Befehl ausführen, sieht die Dateideskriptortabelle folgendermaßen aus:
Jetzt verarbeitet Bash Umleitungen von links nach rechts. Zuerst werden 2> & 1 angezeigt, sodass stderr in stdout dupliziert wird. Die Dateideskriptortabelle lautet:
Jetzt sieht Bash die zweite Weiterleitung
>file
und leitet stdout in die Datei um:Sehen Sie, was hier passiert? Stdout zeigt jetzt auf die Datei, aber der stderr zeigt immer noch auf das Terminal! Alles, was in stderr geschrieben wird, wird immer noch auf dem Bildschirm ausgedruckt! Seien Sie also sehr, sehr vorsichtig mit der Reihenfolge der Weiterleitungen!
Beachten Sie auch, dass in Bash schriftlich
ist genau das gleiche wie:
quelle
>&
/dev/tty0
?Die Zahlen beziehen sich auf die Dateideskriptoren (fd).
stdin
stdout
stderr
2>&1
leitet fd 2 zu 1 um.Dies funktioniert für eine beliebige Anzahl von Dateideskriptoren, wenn das Programm diese verwendet.
Sie können sehen,
/usr/include/unistd.h
wenn Sie sie vergessen:Das heißt, ich habe C-Tools geschrieben, die nicht standardmäßige Dateideskriptoren für die benutzerdefinierte Protokollierung verwenden, sodass Sie sie nur sehen, wenn Sie sie in eine Datei oder etwas anderes umleiten.
quelle
Dieses Konstrukt sendet den Standardfehlerstrom (
stderr
) an den aktuellen Speicherort der Standardausgabe (stdout
) - dieses Währungsproblem scheint von den anderen Antworten vernachlässigt worden zu sein.Mit dieser Methode können Sie jedes Ausgabehandle auf ein anderes umleiten. Am häufigsten wird es jedoch verwendet, um Kanäle
stdout
undstderr
Streams zur Verarbeitung in einen einzelnen Stream zu kanalisieren .Einige Beispiele sind:
Beachten Sie, dass das letzte wird nicht direkt
stderr
zuoutfile2
- es leitet es zu dem, wasstdout
war , wenn das Argument angetroffen wurde (outfile1
) und dann Umleitungenstdout
zuoutfile2
.Dies erlaubt einige ziemlich raffinierte Tricks.
quelle
some_program 2>&1 > /dev/null
funktioniert nicht so :some_program > /dev/null 2>&1
.2>&1
ist ein POSIX-Shell-Konstrukt. Hier ist eine Aufschlüsselung, Token für Token:2
: Deskriptor der Ausgabedatei " Standardfehler ".>&
: Duplizieren Sie einen Operator für den Ausgabedateideskriptor (eine Variante des Operators für die Umleitung der Ausgabe>
). Gegeben ist[x]>&[y]
, dass der mit bezeichnete Dateideskriptorx
eine Kopie des Ausgabedateideskriptors isty
.1
Deskription der Ausgabedatei " Standardausgabe ".Der Ausdruck
2>&1
kopiert den Dateideskriptor1
an den Speicherort2
, sodass jede Ausgabe,2
in die in der Ausführungsumgebung geschrieben wurde ("Standardfehler"), in dieselbe Datei verschoben wird, die ursprünglich von1
("Standardausgabe") beschrieben wurde.Weitere Erklärung:
Dateideskriptor : "Eine pro Prozess eindeutige, nicht negative Ganzzahl, mit der eine geöffnete Datei zum Zweck des Dateizugriffs identifiziert wird."
Standardausgabe / -fehler : Beachten Sie den folgenden Hinweis im Abschnitt Umleitung der Shell-Dokumentation:
quelle
2 ist der Konsolenstandardfehler.
1 ist die Standardausgabe der Konsole.
Dies ist das Standard-Unix, und Windows folgt auch dem POSIX.
ZB wenn du rennst
Der Standardfehler wird zur Standardausgabe umgeleitet, sodass Sie beide Ausgaben zusammen sehen können:
Nach der Ausführung können Sie die gesamte Ausgabe einschließlich der Fehler in der Datei debug.log anzeigen.
Dann geht die Standardausgabe zu out.log und der Standardfehler zu err.log.
Ich schlage vor, dass Sie versuchen, diese zu verstehen.
quelle
perl test.pl > debug.log 2>&1
So beantworten Sie Ihre Frage: Es nimmt jede Fehlerausgabe (normalerweise an stderr gesendet) und schreibt sie in die Standardausgabe (stdout).
Dies ist beispielsweise bei "more" hilfreich, wenn Sie für alle Ausgaben ein Paging benötigen. Einige Programme drucken beispielsweise Nutzungsinformationen in stderr.
Um Ihnen zu helfen, sich zu erinnern
"2> & 1" zeigt einfach alles, was an stderr gesendet wurde, stattdessen auf stdout.
Ich empfehle auch, diesen Beitrag über Fehlerumleitungen zu lesen, in denen dieses Thema ausführlich behandelt wird.
quelle
Aus Sicht eines Programmierers bedeutet dies genau Folgendes:
Siehe die Manpage .
Zu verstehen, dass dies
2>&1
eine Kopie ist, erklärt auch, warum ...... ist nicht dasselbe wie ...
Der erste sendet beide Streams an
file
, während der zweite Fehler anstdout
und die normale Ausgabe an sendetfile
.quelle
Ich fand das sehr hilfreich, wenn Sie ein Anfänger sind, lesen Sie dies
Update:
Unter Linux oder Unix System senden Programme zwei Ausgaben an: Standardausgabe (stdout) und Standardfehler (stderr). Sie können diese Ausgabe in eine beliebige Datei umleiten.
Wenn Sie dies tun, wird
ls -a > output.txt
nichts in der Konsole gedruckt. Alle Ausgaben (stdout) werden in die Ausgabedatei umgeleitet.
Wenn Sie versuchen, den Inhalt einer Datei zu drucken, die nicht beendet wird, bedeutet dies, dass die Ausgabe ein Fehler ist, wie wenn Sie test.txt drucken, das im aktuellen Verzeichnis nicht vorhanden
cat test.txt > error.txt
ist
Die Datei error.txt ist jedoch leer, da wir das stdout in eine Datei umleiten, die nicht stderr ist.
Daher benötigen wir einen Dateideskriptor (ein Dateideskriptor ist nichts anderes als eine positive Ganzzahl, die eine geöffnete Datei darstellt. Sie können sagen, dass der Deskriptor eine eindeutige ID der Datei ist), um der Shell mitzuteilen, welche Art von Ausgabe wir an die Datei senden. Im Unix / Linux-System 1 ist für stdout und 2 für stderr .
Wenn Sie dies jetzt tun,
ls -a 1> output.txt
bedeutet dies, dass Sie die Standardausgabe (stdout) an output.txt senden.und wenn Sie dies tun,
cat test.txt 2> error.txt
bedeutet dies, dass Sie Standard Error (stderr) an error.txt senden.&1
wird verwendet, um auf den Wert des Dateideskriptors 1 (stdout) zu verweisen.Jetzt
2>&1
bedeutet der Punkt "Leiten Sie den stderr an dieselbe Stelle um, an der wir den stdout umleiten".Jetzt können Sie dies tun
cat maybefile.txt > output.txt 2>&1
Sowohl die Standardausgabe (stdout) als auch der Standardfehler (stderr) werden zu output.txt umgeleitet.
Vielen Dank an Ondrej K. für den Hinweis
quelle
Leute, erinnert euch immer an den Hinweis von paxdiablo über den aktuellen Standort des Umleitungsziels ... Es ist wichtig.
Meine persönliche Mnemonik für den
2>&1
Bediener lautet:&
als Bedeutung'and'
oder'add'
Stellen (der Charakter ist ein Amper - und nicht wahr ?)2
(stderr) wohin1
(stdout) bereits / aktuell ist und beide Streams hinzufügen ' .Die gleiche Mnemonik funktioniert auch für die andere häufig verwendete Umleitung
1>&2
:&
Bedeutungand
oderadd
... (Sie haben eine Vorstellung vom kaufmännischen Und, ja?)1
(stdout) dorthin, wo2
(stderr) bereits / aktuell ist und beide Streams hinzufügen ' .Und denken Sie immer daran: Sie müssen Umleitungsketten "vom Ende" von rechts nach links ( nicht von links nach rechts) lesen .
quelle
Ref:
Geben Sie ein
/^REDIRECT
, um zu demredirection
Abschnitt zu gelangen, und erfahren Sie mehr ...Eine Online-Version finden Sie hier: 3.6 Weiterleitungen
PS:
Die meiste Zeit
man
war das mächtige Werkzeug, um Linux zu lernen.quelle
Vorausgesetzt, dass
/foo
dies auf Ihrem System nicht vorhanden ist und/tmp
…druckt den Inhalt von
/tmp
und druckt eine Fehlermeldung für/foo
sendet den Inhalt von
/tmp
an/dev/null
und druckt eine Fehlermeldung für/foo
wird genau das gleiche tun (beachten Sie die 1 )
druckt den Inhalt von
/tmp
und sendet die Fehlermeldung an/dev/null
sendet sowohl die Auflistung als auch die Fehlermeldung an
/dev/null
ist eine Abkürzung
quelle
Dies ist wie das Übergeben des Fehlers an das Standardout oder das Terminal.
Das heißt,
cmd
ist kein Befehl:Der Fehler wird wie folgt an die Datei gesendet:
Standardfehler wird an das Terminal gesendet.
quelle
0 für Eingabe, 1 für stdout und 2 für stderr.
Ein Tipp :
somecmd >1.txt 2>&1
ist richtig, währendsomecmd 2>&1 >1.txt
völlig falsch ohne Wirkung!quelle
unix_commands 2>&1
Dies wird verwendet, um Fehler auf das Terminal zu drucken.
Das Folgende veranschaulicht den Prozess
&2
"Puffer" geschrieben, auf den der Standardfehlerstrom2
verweist.&1
"Puffer" geschrieben, auf den der Standardausgabestream1
verweist.Nehmen Sie also den
unix_commands
Standardfehlerstrom2
und leiten Sie>
den Strom (der Fehler) an die Standardausgabespeicheradresse um&1
, damit sie zum Terminal gestreamt und gedruckt werden.quelle