3178 Stimmen

Was bedeutet in der Shell "2>&1"?

Wenn ich in einer Unix-Shell Folgendes kombinieren möchte stderr y stdout in die stdout stream für weitere Manipulationen kann ich am Ende meines Befehls folgendes anhängen:

2>&1

Wenn ich also Folgendes verwenden möchte head auf die Ausgabe von g++ kann ich so etwas tun:

g++ lots_of_errors 2>&1 | head

so dass ich nur die ersten paar Fehler sehen kann.

Ich habe immer Schwierigkeiten, mir das zu merken, und muss es immer wieder nachschlagen, vor allem, weil ich die Syntax dieses speziellen Tricks nicht ganz verstehe.

Kann jemand das aufschlüsseln und Zeichen für Zeichen erklären, was 2>&1 bedeutet?

63 Stimmen

@dbr Ich glaube nicht, dass es nur an der Bash liegt - ich glaube, es ist eine Sache der Bourne-Shell; daher sh, bash, ksh, ash, dash, usw.

8 Stimmen

Dies ist Teil des Umleitungsparagraphen, der POSIX-konforme Shells oder kurz POSIX-Shells beschreibt. ksh ist zum Beispiel eine POSIX-Shell. Siehe: pubs.opengroup.org/onlinepubs/009695399/utilities/

19 Stimmen

Dieses Konstrukt funktioniert auch unter Windows.

65voto

paxdiablo Punkte 809679

Dieses Konstrukt sendet den Standardfehlerstrom ( stderr ) zum aktuell Ort der Standardausgabe ( stdout ) - diese Währungsfrage scheint in den anderen Antworten vernachlässigt worden zu sein.

Sie können jedes Ausgabe-Handle zu einem anderen umleiten, indem Sie diese Methode verwenden, aber sie wird am häufigsten verwendet, um die stdout y stderr Streams in einen einzigen Stream zur Verarbeitung zusammen.

Einige Beispiele sind:

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

Beachten Sie, dass der letzte Punkt no direkt stderr a outfile2 - es leitet sie um auf das, was stdout war, als das Argument aufgetreten ist ( outfile1 ) und dann leitet um. stdout a outfile2 .

Dies ermöglicht einige ziemlich ausgeklügelte Tricksereien.

5 Stimmen

Obwohl das letzte Beispiel viel klarer wäre als: foo >outfile2 2>outfile1

5 Stimmen

Klarer, ja, aber das würde nicht den "positionellen" Charakter der Umleitung zeigen. Das Beispiel ist konstruiert, da es in der Regel nicht sinnvoll ist, dies in einer einzigen Zeile zu tun - die Methode ist wirklich nützlich, wenn verschiedene Parteien für die verschiedenen Teile der Umleitung verantwortlich sind. Zum Beispiel, wenn ein Skript einen Teil der Umleitung übernimmt und Sie es mit einem anderen Teil ausführen.

6 Stimmen

Mir ist gerade klar geworden, dass das letzte Beispiel auch eine lange bestehende Verwirrung löst, die ich darüber hatte, warum das so ist: some_program 2>&1 > /dev/null funktioniert nicht auf diese Weise: some_program > /dev/null 2>&1 .

65voto

kundan bora Punkte 687

Ich fand dies sehr hilfreich, wenn Sie ein Anfänger sind lesen diese

Aktualisierung:
In Linux- oder Unix-Systemen gibt es zwei Stellen, an die Programme ihre Ausgaben senden: Standardausgabe (stdout) und Standardfehler (stderr) Sie können diese Ausgaben in eine beliebige Datei umleiten.

Zum Beispiel, wenn Sie dies tun

ls -a > output.txt

Es wird nichts in der Konsole ausgegeben alle Ausgaben (stdout) wird in die Ausgabedatei umgeleitet.

Und wenn Sie versuchen, den Inhalt einer Datei zu drucken, die nicht beendet ist, wird ein Fehler ausgegeben, z.B. wenn Sie test.txt drucken, die nicht im aktuellen Verzeichnis vorhanden ist

cat test.txt > error.txt

Die Ausgabe wird sein

cat: test.txt :No such file or directory

Die Datei error.txt wird jedoch leer sein, da wir stdout in eine Datei umleiten und nicht stderr.

Wir brauchen also einen Dateideskriptor (Ein Dateideskriptor ist nichts anderes als eine positive ganze Zahl, die eine geöffnete Datei darstellt. Man kann sagen, dass der Deskriptor die eindeutige Kennung der Datei ist), um der Shell mitzuteilen, welche Art von Ausgabe wir an die Datei senden. In Unix/Linux-Systemen 1 ist für stdout und 2 für stderr .

Wenn Sie also Folgendes tun

ls -a 1> output.txt bedeutet, dass Sie die Standardausgabe (stdout) an output.txt senden.

und wenn Sie dies tun

cat test.txt 2> error.txt bedeutet, dass Sie den Standardfehler (stderr) an error.txt senden.

&1 wird verwendet, um auf den Wert des Dateideskriptors 1 (stdout) zu verweisen.

Nun zur Sache 2>&1 bedeutet "stderr an denselben Ort umleiten, an den wir stdout umleiten".

Jetzt können Sie dies tun
<br

cat maybefile.txt > output.txt 2>&1

werden sowohl die Standardausgabe (stdout) als auch die Standardfehler (stderr) in die Datei output.txt umgeleitet.

Dank an Ondrej K. für den Hinweis auf

1 Stimmen

+1 für "&1 wird verwendet, um den Wert des Dateideskriptors 1 (stdout) zu referenzieren.". Ich habe mich immer gefragt, warum es nicht einfach 2>1

28voto

Marcus Thornton Punkte 5451

2 ist der Standardfehler der Konsole.

1 ist die Standardausgabe der Konsole.

Dies ist der Unix-Standard, und auch Windows folgt dem POSIX.

Wenn Sie z.B. Folgendes ausführen

perl test.pl 2>&1

wird der Standardfehler auf die Standardausgabe umgeleitet, so dass Sie beide Ausgaben zusammen sehen können:

perl test.pl > debug.log 2>&1

Nach der Ausführung können Sie alle Ausgaben, einschließlich der Fehler, in der Datei debug.log sehen.

perl test.pl 1>out.log 2>err.log

Die Standardausgabe wird dann in out.log und der Standardfehler in err.log gespeichert.

Ich schlage vor, dass Sie versuchen, diese zu verstehen.

0 Stimmen

Das zweite Beispiel ist falsch: als Rangfolge STDERR wird umgeleitet zu STDOUT nur Standard STDOUT wird geschrieben in debug.log (nicht STDERR ) siehe meine Antwort (der Absatz #2)! Um sicherzustellen beide auf dieselbe Datei umgeleitet werden sollen, müssen Sie die Umleitungsanweisungen umkehren: perl test.pl > debug.log 2>&1

25voto

wjordan Punkte 18512

2>&1 ist ein POSIX-Shell-Konstrukt. Hier ist eine Aufschlüsselung, Token für Token:


2 : " Standardfehler Ausgabedatei-Deskriptor".

>& : Duplizieren eines Ausgabedatei-Deskriptors Operator (eine Variante von Ausgang Umleitung Betreiber > ). Bei [x]>&[y] der Dateideskriptor mit der Bezeichnung x wird als Kopie des Deskriptors der Ausgabedatei erstellt y .

1 " Standard-Ausgang Ausgabedatei-Deskriptor".

Der Ausdruck 2>&1 kopiert den Dateideskriptor 1 zum Standort 2 so dass jede Ausgabe, die in 2 ("Standardfehler") in der Ausführungsumgebung geht in dieselbe Datei, die ursprünglich durch 1 ("Standardausgabe").


Weitere Erklärung:

Datei Deskriptor : "Eine prozessspezifisch eindeutige, nicht-negative Ganzzahl, die zur Identifizierung einer geöffneten Datei zum Zweck des Dateizugriffs verwendet wird."

Standardausgabe/Fehler : Beachten Sie den folgenden Hinweis im Umleitung Abschnitt der Shell-Dokumentation:

Offene Dateien werden durch Dezimalzahlen dargestellt, die mit Null beginnen. Der größtmögliche Wert wird von der Implementierung festgelegt; alle Implementierungen müssen jedoch mindestens die Werte 0 bis einschließlich 9 zur Verwendung durch die Anwendung unterstützen. Diese Zahlen werden als "Dateideskriptoren" bezeichnet. Die Werte 0, 1 und 2 haben eine besondere Bedeutung und konventionelle Verwendung und werden durch bestimmte Umleitungsoperationen impliziert; sie werden als Standardeingabe, Standardausgabe bzw. Standardfehler bezeichnet. Programme nehmen ihre Eingaben normalerweise von der Standardeingabe entgegen und geben ihre Ausgaben auf der Standardausgabe aus. Fehlermeldungen werden normalerweise auf Standardfehler geschrieben. Den Umleitungsoperatoren können eine oder mehrere Ziffern vorangestellt werden (ohne dazwischen liegende Zeichen), um die Nummer des Dateideskriptors zu bezeichnen.

20voto

Andrioid Punkte 3330

Um Ihre Frage zu beantworten: Es nimmt alle Fehlerausgaben (die normalerweise auf stderr gesendet werden) und schreibt sie auf die Standardausgabe (stdout).

Dies ist z. B. bei 'more' hilfreich, wenn Sie die gesamte Ausgabe auslagern wollen. Einige Programme geben gerne Nutzungsinformationen in stderr aus.

Damit Sie sich erinnern können

  • 1 = Standardausgabe (wo Programme normale Ausgaben machen)
  • 2 = Standardfehler (wo Programme Fehler ausgeben)

"2>&1" leitet einfach alles, was an stderr gesendet wird, an stdout weiter.

Ich empfehle auch die Lektüre dieser Beitrag zur Fehlerumleitung wo dieses Thema ausführlich behandelt wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X