Einer der weniger einleuchtenden Shell-Operatoren ist der Operator
>&. Den Klassiker, die Umlenkung von stdout und stderr
in eine Datei,
kennt jeder, der häufiger unter Unix unterwegs ist. Es stellt sich
dabei aber immer leicht die Frage: Wie war das nochmal? Muss 2>&1
vor der Umlenkung >/tmp/file stehen? Oder dahinter? Gleichgültig
ist die Reihenfolge jedenfalls nicht.
Die Beschreibung auf der Bash-Manpage ist recht knapp:
The operator [n]>&word is used to duplicate output file descriptors.
If word expands to one or more digits, the file descriptor denoted
by n is made to be a copy of that file descriptor. If n is
not specified, the standard output (file descriptor 1) is used.
Das heißt, man kann den Operator N>&M als Zuweisung verstehen: Das
Ausgabeziel (Terminal, Datei oder Pipe), das seitens des schreibenden
Prozesses über Deskriptor M erreicht wird, wird von der Shell
(zusätzlich) mit Deskriptor N verbunden. Alles, was der schreibende
Prozess auf Desktiptor N schreibt, gelangt somit an das gleiche
Ziel wie das, was er auf Deskriptor M schreibt. Liegen mehrere
Umlenkungsoperationen vor, werden diese von links nach rechts ausgewertet.
Es folgen einige Anwendungsfälle.
Stderr und stdout gemeinsam auf eine Pipe lenken
-
Deskriptor 1 (stdout) von cmd1 wird von der Shell mit
der Pipe verbunden (|).
-
Deskriptor 2 (stderr) wird ebenfalls mit der Pipe verbunden (2>&1).
Ergebnis: stdout und stderr gehen auf die Pipe.
Stderr statt stdout auf eine Pipe lenken
$ cmd1 2>&1 >/dev/null | cmd2
-
Deskriptor 1 (stdout) von cmd1 wird von der Shell mit der Pipe
verbunden (|).
-
Deskriptor 2 (stderr) wird ebenfalls mit der Pipe verbunden (2>&1).
-
Deskriptor 1 (stdout) wird mit /dev/null verbunden (>/dev/null).
Ergebnis: stderr geht auf die Pipe, stdout geht nach /dev/null.
Stdout und stderr vertauschen
$ cmd 3>&1 1>&2 2>&3 3>&-
-
Deskriptor 3 geht auf das gleiche Ziel wie Deskriptor 1 (3>&1).
-
Deskriptor 1 geht auf das gleiche Ziel wie Deskriptor 2 (1>&2).
-
Deskriptor 2 geht auf das gleiche Ziel wie Deskriptor 3 (2>&3).
-
Gib Deskriptor 3 frei (3>&-).
Ergebnis: stdout und stderr sind vertauscht.