Was bedeutet "2> 1" in einer Shell?

Wenn ich in einer Unix-Shell stderr und stdout zur weiteren Verarbeitung zu einem Stream von stdout kombinieren möchte, kann ich am Ende meines Befehls Folgendes hinzufügen:

 2>> 

Wenn ich also head für die Ausgabe von g ++ verwenden möchte, kann ich Folgendes tun:

 g++ lots_of_errors 2> | head 

daher sehe ich nur die ersten paar fehler.

Es fällt mir immer schwer, mich daran zu erinnern, und ich muss ständig danach suchen, und das liegt hauptsächlich daran, dass ich die Syntax dieses speziellen Tricks nicht vollständig verstehe. Kann jemand es aufschlüsseln und den Charakter für Charakter erklären, was "2> und 1" bedeutet?

1554
04 мая '09 в 1:57 2009-05-04 01:57 Tristan Havelick fragte am 04. Mai 09 um 1:57 2009-05-04 01:57
@ 16 Antworten

Der Dateideskriptor 1 ist die Standardausgabe (stdout).
Der Dateideskriptor 2 ist ein Standardfehler (stderr).

Hier ist eine Möglichkeit, sich an dieses Konstrukt zu erinnern (obwohl dies nicht ganz genau ist): Zunächst kann 2>1 als eine gute Möglichkeit angesehen werden, stderr auf stdout umzuleiten. In der Tat wird es jedoch als "umleiten stderr auf eine Datei namens 1 " interpretiert. > gibt an, dass der nächste der Dateideskriptor ist, nicht der Dateiname. Die Konstruktion lautet also: 2>> .

1763
04 мая '09 в 2:04 2009-05-04 02:04 antwortete Ayman Hourieh am 04 Mai '09 um 2:04 2009-05-04 02:04
 echo test > afile.txt 

.. leitet stdout zu afile.txt . Das ist dasselbe wie zu tun.

 echo test 1> afile.txt 

Um stderr umzuleiten, müssen Sie ...

 echo test 2> afile.txt 

>> ist die Syntax zum Umleiten eines Streams zu einem anderen Dateideskriptor - 0 ist stdin. 1 - Standardausgabe. 2 - stderr.

border=0

Sie können stdout zu stderr umleiten, indem Sie ..

 echo test 1> # or echo test >> 

.. oder umgekehrt:

 echo test 2>> 

So kürzer .. 2> leitet stderr in eine (nicht spezifizierte) Datei um und fügt > stderr zu stdout um

436
04 мая '09 в 1:59 2009-05-04 01:59 Die Antwort wird am 04. Mai '09 um 1:59 2009-05-04 01:59 gegeben

Einige Umleitungs-Tricks

Einige Syntaxfunktionen in diesem Bereich können ein wichtiges Verhalten haben. Es gibt mehrere kleine Beispiele für Umleitungen, STDERR , STDOUT und Bestellargumente .

1 - Überschreiben oder hinzufügen?

Das Symbol > zeigt die Umleitung an.

  • > bedeutet, die komplette Datei als Ganzes zu senden und das Ziel neu zu schreiben, falls es existiert (siehe noclobber Bash-Funktion unter Nr. 3).
  • >> bedeutet, dass der Versand zum Ziel hinzugefügt wird, wenn es existiert.

In jedem Fall wird die Datei erstellt, wenn sie nicht vorhanden ist.

2 - Shell-Befehlszeile hängt von der Reihenfolge ab !!

Um dies zu testen, benötigen wir einen einfachen Befehl, der etwas an beide Ausgänge sendet:

 $ ls -ld /tmp /tnt ls: cannot access /tnt: No such file or directory drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp $ ls -ld /tmp /tnt >/dev/null ls: cannot access /tnt: No such file or directory $ ls -ld /tmp /tnt 2>/dev/null drwxrwxrwt 118 root root 196608 Jan 7 11:49 /tmp 

(Es wird erwartet, dass Sie nicht über ein Verzeichnis mit dem Namen /tnt verfügen;). Nun, wir haben es!

Also mal sehen:

 $ ls -ld /tmp /tnt >/dev/null ls: cannot access /tnt: No such file or directory $ ls -ld /tmp /tnt >/dev/null 2> $ ls -ld /tmp /tnt 2> >/dev/null ls: cannot access /tnt: No such file or directory 

Der letzte STDERR Befehlszeilenauszug auf der Konsole scheint nicht das erwartete Verhalten zu sein ... Aber ...

Wenn Sie Nachrichten über einen Ausgang, den anderen oder beide Nachrichten filtern möchten:

 $ ls -ld /tmp /tnt | sed 's/^.*$/<--  --->/' ls: cannot access /tnt: No such file or directory <-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp ---> $ ls -ld /tmp /tnt 2> | sed 's/^.*$/<--  --->/' <-- ls: cannot access /tnt: No such file or directory ---> <-- drwxrwxrwt 118 root root 196608 Jan 7 12:02 /tmp ---> $ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<--  --->/' ls: cannot access /tnt: No such file or directory $ ls -ld /tmp /tnt >/dev/null 2> | sed 's/^.*$/<--  --->/' $ ls -ld /tmp /tnt 2> >/dev/null | sed 's/^.*$/<--  --->/' <-- ls: cannot access /tnt: No such file or directory ---> 

Beachten Sie, dass der letzte Befehl in diesem Absatz genau derselbe ist wie in dem vorherigen Absatz, in dem ich geschrieben habe. Es scheint nicht das erwartete Verhalten zu sein (daher kann es sogar das erwartete Verhalten sein).

Nun, es gibt ein paar Umleitungs-Tricks für unterschiedliche Operationen an beiden Ausgängen :

 $ ( ls -ld /tmp /tnt | sed 's/^/O: /' > ) 9> 2> | sed 's/^/E: /' O: drwxrwxrwt 118 root root 196608 Jan 7 12:13 /tmp E: ls: cannot access /tnt: No such file or directory 

Anmerkung: Der > Deskriptor wird aufgrund von ) 9>> spontan auftreten.

Nachtrag: nota! Mit der neuen Version von ( >4.0 ) sind eine neue Funktion und eine sexuellere Syntax für solche Aktionen erschienen:

 $ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /') O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp E: ls: cannot access /tnt: No such file or directory 

Zum Schluss noch dieses kaskadierte Ausgabeformat:

 $ ((ls -ld /tmp /tnt |sed 's/^/O: /' > ) 2> |sed 's/^/E: /') 9> cat -n 1 O: drwxrwxrwt 118 root root 196608 Jan 7 12:29 /tmp 2 E: ls: cannot access /tnt: No such file or directory 

Nachtrag: nota! Dieselbe Syntax in beiden Richtungen:

 $ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')) 1 O: drwxrwxrwt 17 root root 28672 Nov 5 23:00 /tmp 2 E: ls: cannot access /tnt: No such file or directory 

Wenn STDOUT einen bestimmten Filter durchläuft, durchlaufen STDERR den anderen und schließlich beide Ausgänge kombiniert den dritten Befehlsfilter.

3 - Ein Wort zu noclobber und Syntax >|

Was ist mit dem Überschreiben :

Während set -o noclobber bash anweist, vorhandene Dateien nicht zu überschreiben, lautet die Syntax >| Erlaubt Ihnen, diese Grenze zu überschreiten:

 $ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX) $ date > $testfile ; cat $testfile Mon Jan 7 13:18:15 CET 2013 $ date > $testfile ; cat $testfile Mon Jan 7 13:18:19 CET 2013 $ date > $testfile ; cat $testfile Mon Jan 7 13:18:21 CET 2013 

Die Datei wird jedes Mal überschrieben, nun aber:

 $ set -o noclobber $ date > $testfile ; cat $testfile bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file Mon Jan 7 13:18:21 CET 2013 $ date > $testfile ; cat $testfile bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file Mon Jan 7 13:18:21 CET 2013 

Durchgehen >| :

 $ date >| $testfile ; cat $testfile Mon Jan 7 13:18:58 CET 2013 $ date >| $testfile ; cat $testfile Mon Jan 7 13:19:01 CET 2013 

Trennen Sie diese Option und / oder fordern Sie an, wenn sie bereits installiert ist.

 $ set -o | grep noclobber noclobber on $ set +o noclobber $ set -o | grep noclobber noclobber off $ date > $testfile ; cat $testfile Mon Jan 7 13:24:27 CET 2013 $ rm $testfile 

4 - Der letzte Trick und mehr ...

Um beide Ausgaben von diesem Befehl umzuleiten, sehen Sie, dass die korrekte Syntax Folgendes sein kann:

 $ ls -ld /tmp /tnt >/dev/null 2>> 

Für diesen speziellen Fall gibt es eine Abkürzungssyntax: > ... oder >>

 $ ls -ld /tmp /tnt  $ ls -ld /tmp /tnt >> 

Hinweis: Wenn 2>> vorhanden ist, ist 1>> auch die richtige Syntax:

 $ ls -ld /tmp /tnt 2>/dev/null 1>> 

4b Jetzt werde ich dich denken lassen:

 $ ls -ld /tmp /tnt 2> 1> | sed -es/^/++/ ++/bin/ls: cannot access /tnt: No such file or directory ++drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/ $ ls -ld /tmp /tnt 1> 2> | sed -es/^/++/ /bin/ls: cannot access /tnt: No such file or directory drwxrwxrwt 193 root root 196608 Feb 9 11:08 /tmp/ 

4c- Wenn Sie an detaillierteren Informationen interessiert sind

Sie können den Graceful Guide lesen, indem Sie auf Folgendes klicken:

 man -Len -Pless\ +/^REDIRECTION bash 

in Konsole; )

228
29 апр. Die Antwort gibt F. Hauri 29. April 2013-04-29 19:33 '13 am 19:33 2013-04-29 19:33
  • 2 ist der Standarddateideskriptor für stderr.
  • 1 ist der Standarddateibeschreiber für stdout.
  • >> ist die Shell-Syntax für "den vorherigen (ersten) Dateideskriptor auf den nächsten (zweiten) Dateideskriptor reduzieren".
112
03 дек. Die Antwort gibt Bill Karwin am 03. Dezember. 2017-12-03 01:38 '17 am 1:38 2017-12-03 01:38

Zahlen beziehen sich auf Dateideskriptoren (fd).

  • Null stdin
  • Ein stdout
  • Zwei stderr

2>> leitet fd 2 auf 1 um.

Dies funktioniert für eine beliebige Anzahl von Dateideskriptoren, wenn das Programm sie verwendet.

Sie können /usr/include/unistd.h wenn Sie sie vergessen:

  #define STDIN_FILENO 0  #define STDOUT_FILENO 1  #define STDERR_FILENO 2  

Ich habe jedoch C-Tools geschrieben, die nicht standardmäßige Datei-Handles für die benutzerdefinierte Protokollierung verwenden. Sie können sie also nicht sehen, wenn Sie sie nicht in eine Datei oder ähnliches umleiten.

59
04 мая '09 в 1:58 2009-05-04 01:58 antwortete Colin Burnett am 04. Mai 09 um 01:58 2009-05-04 01:58

Dieses Konstrukt sendet den Standardfehlerstrom ( stderr ) an die aktuelle Position der Standardausgabe ( stdout ). stdout Problem mit der Währung scheint von anderen Antworten ignoriert worden zu sein.

Sie können mit dieser Methode jeden Ausgabedeskriptor auf einen anderen umleiten, meist werden sie jedoch verwendet, um stdout und stderr Streams zur Verarbeitung an einen einzelnen Stream zu leiten.

Einige Beispiele sind:

 # Look for ERROR string in both stdout and stderr. foo 2> | grep ERROR # Run the less pager without stderr screwing up the output. foo 2> | less # Send stdout/err to file (with append) and terminal. foo 2> |tee /dev/tty >>outfile # Send stderr to normal location and stdout to file. foo >outfile1 2> >outfile2 

Beachten Sie, dass der letzte outfile2 nicht stderr auf outfile2 umleitet - er leitet ihn an den outfile2 stdout um, als das Argument erfüllt wurde ( outfile1 ), und leitet stdout auf outfile2 .

Dies ermöglicht die Verwendung eines ziemlich komplexen Betrugs.

45
04 мая '09 в 2:54 2009-05-04 02:54 Die Antwort ist gegeben paxdiablo 04 Mai '09 um 2:54 2009-05-04 02:54

Ich habe diesen genialen Beitrag in Weiterleitung gefunden: Alles über Weiterleitungen

Leiten Sie sowohl die Standardausgabe als auch den Standardfehler in eine Datei um

$ -Befehl Datei

Diese einzeilige Anweisung verwendet den Operator um beide Ausgabeströme - stdout und stderr - vom Befehl in die Datei umzuleiten. Dies ist eine Bash-Verknüpfung, um beide Streams schnell zum selben Ziel umzuleiten.

So sieht die Dateideskriptortabelle aus, nachdem bash beide Threads umgeleitet hat: 2019

29 окт. Antwort von Deen John am 29. Oktober 2016-10-29 16:04 '16 um 16:04 Uhr 2016-10-29 16:04

2 - Standardfehler der Konsole.

1 - Standard-Konsolenausgabe.

Dies ist ein Standard-Unix, Windows folgt ebenfalls POSIX. Zum Beispiel beim Start

 perl test.pl 2>> 

Der Standardfehler wird zur Standardausgabe umgeleitet, sodass Sie beide Ausgänge zusammen sehen können.

 perl test.pl > debug.log 2>> 

Nach der Ausführung können Sie die gesamte Ausgabe einschließlich der Fehler in debug.log anzeigen.

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

Dann geht die Standardausgabe in out.log und der Standardfehler in err.log.

Ich schlage vor, Sie versuchen, sie zu verstehen.

12
19 июля '13 в 6:23 2013-07-19 06:23 Die Antwort gibt Marcus Thornton am 19. Juli 13 um 6:23 Uhr 2013-07-19 06:23

Um Ihre Frage zu beantworten: Es akzeptiert jede Fehlerausgabe (normalerweise an stderr gesendet) und schreibt sie in die Standardausgabe (stdout).

Dies ist beispielsweise nützlich, wenn Sie für die gesamte Ausgabe ein Paging benötigen. Einige Programme, z. B. das Drucken von Nutzungsinformationen in stderr.

Um Ihnen zu helfen, sich zu erinnern

  • 1 = Standardausgabe (bei der normale Ausgabe von Programmen gedruckt wird)
  • 2 = Standardfehler (wo Programme Fehler drucken)

"2> 1" gibt einfach alles an stderr an, anstatt stdout.

Ich empfehle auch, diesen Beitrag zu lesen, wenn Fehler umgeleitet werden, bei denen dieses Problem ausführlich behandelt wird.

12
04 мая '09 в 2:24 2009-05-04 02:24 Die Antwort gibt Andrioid am 04. Mai 09 um 02:24 2009-05-04 02:24

2>> ist ein POSIX-Shell-Konstrukt. Hier ist die Aufteilung, das Token mit dem Token:


2 : Beschreibung der Ausgabedatei Standardfehler .

>> : Dupliziere den Ausgabedateibeschreiber (Option Ausgabeoperator umleiten > ). Mit [x]>> wird der mit x bezeichnete Dateideskriptor eine Kopie des Ausgabedateideskriptors y .

1 Handle " Standardausgabe " für die Ausgabedatei.

Ausdruck 2>> kopiert den Dateideskriptor 1 an Position 2 , sodass alle in der Laufzeitumgebung auf 2 geschriebenen Ausgaben ("Standardfehler") in der gleichen Datei abgelegt werden, die ursprünglich 1 beschrieben wurde ("Standardausgabe").


Weitere Erklärung:

Dateideskriptor: "Eine eindeutige Ganzzahl für jeden Prozess, die zum Identifizieren einer geöffneten Datei zum Zugriff auf Dateien verwendet wird."

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

Offene Dateien werden durch Dezimalzahlen dargestellt, beginnend mit Null. Der größtmögliche Wert wird durch die Implementierung bestimmt; Alle Implementierungen müssen jedoch mindestens 0 bis einschließlich 9 zur Verwendung in der Anwendung unterstützen. Diese Nummern werden "Dateideskriptoren" genannt. Die Werte 0, 1 und 2 haben eine besondere Bedeutung und werden normalerweise verwendet. Sie werden durch einige Umleitungsoperationen impliziert. Sie werden als Standardeingabe, Standardausgabe bzw. Standardfehler bezeichnet. Normalerweise nehmen Programme ihre Eingabe von der Standardeingabe und schreiben die Ausgabe in die Standardausgabe. Fehlermeldungen werden normalerweise durch Standardfehler geschrieben. Umleitungsoperatoren können eine oder mehrere Ziffern (ohne Zwischenzeichen) vorangestellt werden, um die Dateideskriptornummer anzugeben.

10
25 дек. Die Antwort ist 25 Dez. 2016-12-25 09:43 '16 um 09:43 Uhr 2016-12-25 09:43

Aus Sicht des Programmierers bedeutet dies genau das:

 dup2(1, 2); 

Siehe die Hilfeseite .

Das Verständnis, dass 2>> eine Kopie ist, erklärt auch, warum ...

 command >file 2>> 

... nicht dasselbe wie ...

 command 2> >file 

Der erste sendet beide Streams an die file und der zweite sendet Fehler an stdout und die übliche Ausgabe an die file .

8
03 дек. die antwort wird ams 03 dec gegeben. 2015-12-03 13:20 '15 um 13:20 Uhr 2015-12-03 13:20

Paxdiablo erinnert sich immer an den Ort der aktuellen Weiterleitungsadresse ... Wichtig .

Meine persönliche Erinnerung für Operator 2>> lautet wie folgt:

  • Stellen Sie sich > als die Bedeutung von 'and' oder 'add' (der Charakter ist Ampersions- und nicht wahr?)
  • So wird es zu: 'redirect 2 (stderr), wobei 1 (stdout) bereits / aktuell ist und beide Streams hinzufügen .

Dieselbe mnemonische Funktion für eine andere häufig verwendete Weiterleitung, 1>> :

  • Denken Sie an > Wert and oder add Sie add ... (Sie haben die Idee eines kaufmännischen Und, oder?)
  • So wird es zu: 'redirect 1 (stdout), wobei 2 (stderr) bereits / derzeit ist und beide Streams hinzufügen .

Und denken Sie immer daran: Sie müssen Umleitungsketten "von Ende" lesen (von rechts nach links ( nicht von links nach rechts)).

4
01 июля '12 в 13:47 2012-07-01 13:47 Die Antwort gibt Kurt Pfeifle am 1. Juli 12 um 13.47 Uhr 2012-07-01 13:47

Dies ist genau dasselbe wie ein Fehler bei der Einstellung für stdout oder terminal. d.h. cmd kein Befehl $ cmd 2> Dateiname cat Dateiname wurde nicht gefunden

Fehler, der an eine Datei wie diese gesendet wurde 2> 1 Fehler an Terminal gesendet

4
11 окт. Antwort gegeben Kalanidhi 11. Oktober 2013-10-11 09:16 13 am 09:16 2013-10-11 09:16

Wenn /foo nicht auf Ihrem System vorhanden ist und /tmp tut ...

 $ ls -l /tmp /foo 

gibt den Inhalt von /tmp und gibt eine Fehlermeldung für /foo

 $ ls -l /tmp /foo > /dev/null 

Senden Sie den Inhalt von /tmp an /dev/null und geben Sie eine Fehlermeldung für /foo

 $ ls -l /tmp /foo 1> /dev/null 

wird dasselbe tun (Anmerkung 1 )

 $ ls -l /tmp /foo 2> /dev/null 

gibt den Inhalt von /tmp und sendet eine Fehlernachricht an /dev/null

 $ ls -l /tmp /foo 1> /dev/null 2> /dev/null 

sendet sowohl die Auflistung als auch die Fehlernachricht an /dev/null

 $ ls -l /tmp /foo > /dev/null 2> > 

ist Abkürzung

2
01 сент. Die Antwort ist gegeben Matijs 01 Sep. 2016-09-01 23:58 16 um 23:58 Uhr 2016-09-01 23:58

Eingabeumleitung

Die Eingabeumleitung bewirkt, dass eine Datei, deren Name das Ergebnis einer Worterweiterung ist, die zum Lesen eines Dateideskriptors n oder einer Standardeingabe (Dateideskriptor 0) geöffnet werden muss, wenn n nicht angegeben ist.

Übliches Format für die Umleitung der Eingabe:

  [n]<word 

Umleitung der Ausgabe

Das Umleiten der Ausgabe bewirkt, dass eine Datei, deren Name von einer Worterweiterung stammt, die zum Schreiben eines Dateideskriptors n oder einer Standardausgabe (Dateideskriptor 1) geöffnet werden muss, wenn n nicht angegeben ist. Wenn die Datei nicht vorhanden ist, wird sie erstellt. Wenn es existiert, wird es auf die Größe Null gekürzt.

Übliches Format zum Umleiten der Ausgabe:

  [n]>word 

Dateideskriptoren verschieben

Operator zum Umleiten von Dateideskriptoren

  [n]<> 

verschiebt die Dateideskriptornummer in den Dateideskriptor n oder die Standardeingabe (Dateideskriptor 0), wenn n nicht angegeben ist. Die Ziffer schließt sich nach dem Duplizieren mit n.

Ebenso der Umleitungsoperator

  [n]>> 

verschiebt die Dateideskriptornummer in den Dateideskriptor n oder die Standardausgabe (Dateideskriptor 1), wenn n nicht angegeben ist.

isy:

man bash
/^REDIRECT , um den redirection zu finden. /^REDIRECT ..

Die Online-Version ist hier:
http://www.gnu.org/software/bash/manual/bashref.html#Redirections

ps:

viel Zeit war der man ein mächtiges Werkzeug, um Linux zu lernen

2
06 июня '15 в 14:07 2015-06-06 14:07 Antwort von yurenchen am 6. Juni 15 um 14:07 2015-06-06 14:07

0 für Eingabe, 1 für stdout und 2 für stderr.

Ein Tipp : somecmd >1.txt 2>> ist korrekt und somecmd 2> >1.txt völlig falsch ohne Wirkung!

0
25 июля '16 в 12:46 2016-07-25 12:46 Die Antwort ist Turtle 25. Juli '16 um 12:46 2016-07-25 12:46 gegeben

Weitere Fragen zu Tags oder zum Stellen einer Frage