Wenn ich in einer Unix-Shell stderr
und stdout
in den stdout
-Stream für weitere Manipulationen zusammenfassen möchte, kann ich am Ende meines Befehls folgendes anhängen:
2>&1
Wenn ich also head
auf die Ausgabe von g++
anwenden möchte, kann ich etwas wie folgt tun:
g++ lots_of_errors 2>&1 | head
damit ich nur die ersten paar Fehler sehen kann.
Ich habe immer Schwierigkeiten, mir das zu merken, und muss ständig nachschlagen, und das liegt vor allem daran, dass ich die Syntax dieses speziellen Tricks nicht ganz verstehe.
Kann mir jemand das aufschlüsseln und Zeichen für Zeichen erklären, was 2>&1
bedeutet?
Dateideskriptor 1 ist die Standardausgabe (stdout
).
Dateideskriptor 2 ist der Standardfehler (stderr
).
Hier ist eine Möglichkeit, sich dieses Konstrukt zu merken (obwohl es nicht ganz korrekt ist): auf den ersten Blick mag 2>1
wie ein guter Weg aussehen, stderr
nach stdout
umzuleiten. Es wird jedoch tatsächlich als "leite stderr
zu einer Datei namens 1
um" interpretiert. Das "&" zeigt an, dass es sich bei dem, was folgt, um einen Dateideskriptor und nicht um einen Dateinamen handelt. Also wird das Konstrukt zu: 2>&1
.
echo test > afile.txt
leitet stdout nach afile.txt
um. Dies ist dasselbe wie die Ausführung von
echo test 1> afile.txt
Um stderr umzuleiten, tun Sie das:
echo test 2> afile.txt
>&
ist die Syntax, um einen Stream auf einen anderen Dateideskriptor umzuleiten - 0 ist stdin, 1 ist stdout, und 2 ist stderr.
Sie können stdout nach stderr umleiten, indem Sie dies tun:
echo test 1>&2 # or echo test >&2
Oder andersherum:
echo test 2>&1
Also, kurz gesagt... 2>
leitet stderr zu einer (nicht spezifizierten) Datei um, das Anhängen von &1
leitet stderr zu stdout um.
Die Zahlen beziehen sich auf die Dateideskriptoren (fd).
stdin
stdout
stderr
2>&1" leitet fd 2 auf 1 um.
Dies funktioniert für eine beliebige Anzahl von Dateideskriptoren, wenn das Programm sie verwendet.
Sie können in /usr/include/unistd.h
nachsehen, wenn Sie sie vergessen haben:
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
Davon abgesehen habe ich C-Tools geschrieben, die nicht-standardisierte Dateideskriptoren für benutzerdefinierte Protokollierung verwenden, so dass man sie nicht sieht, es sei denn, man leitet sie in eine Datei oder so um.