Zusätzlich zu den Unterlagen jordanm Punkte, möchte ich sicherstellen, eine falsche Vorstellung in Ihrer Frage das ausgeführte Programm dargestellt zu korrigieren ist nicht Umleitungen zu behandeln. Es ist ihnen kaum bewusst. Die Shell verarbeitet Weiterleitungen.
Ein Programm wird mit drei geöffneten Dateien gestartet: stdin (# 0), stdout (# 1) und stderr (# 2). Wenn Sie nur ein Programm über Ihre Shell-Eingabeaufforderung ausführen, werden diese mit Ihrem Endgerät verbunden, sodass das Programm liest, was Sie eingeben (stdin), und Ausgabe (stdout) und Fehler (stderr) auf Ihr Terminal druckt.
Als Beispiel laufe ich einfach cat
in einem Terminal (was tty
heißt /dev/pts/31
). Ich kann überprüfen, mit welchen Dateien es geöffnet ist lsof
:
$ lsof -a -p `pidof cat` -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cat 21257 anthony 0u CHR 136,31 0t0 34 /dev/pts/31
cat 21257 anthony 1u CHR 136,31 0t0 34 /dev/pts/31
cat 21257 anthony 2u CHR 136,31 0t0 34 /dev/pts/31
In der Tat können wir sehen, dass das Terminal für alle drei geöffnet ist. Versuchen wir stattdessen einen ziemlich albernen Katzenaufruf : cat < /dev/zero > /dev/null 2>/dev/full
, der alle drei umleitet:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cat 21838 anthony 0r CHR 1,5 0t0 1030 /dev/zero
cat 21838 anthony 1w CHR 1,3 0t0 1028 /dev/null
cat 21838 anthony 2w CHR 1,7 0t0 1031 /dev/full
Die Shell implementierte diese Umleitungen, indem sie die drei Geräte als stdin, stdout und stderr (anstelle des Terminals) übergab. Die Schale implementiert in ähnlicher Weise Rohre. Versuchen wir es cat | dd > /dev/null
(eine ziemlich dumme Pfeife):
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cat 22507 anthony 0u CHR 136,31 0t0 34 /dev/pts/31
cat 22507 anthony 1w FIFO 0,8 0t0 56081395 pipe
cat 22507 anthony 2u CHR 136,31 0t0 34 /dev/pts/31
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
dd 22508 anthony 0r FIFO 0,8 0t0 56081395 pipe
dd 22508 anthony 1u CHR 136,31 0t0 34 /dev/null
dd 22508 anthony 2u CHR 136,31 0t0 34 /dev/pts/31
Beachten Sie, wie die Shell ein Rohr geöffnet hat und es verwendet hat, um das stdout von cat
mit dem stdin von zu verbinden dd
. Und weiter , wie es angeschlossen dd
ist stdout /dev/null
.
Die ausgeführten Befehle kennen die Umleitungen nicht wirklich. Sie verwenden einfach stdin, stdout, stderr wie gewohnt. Dies können alle das Terminal sein oder sie können zu / von einer Datei, einem Gerät oder einer Pipe zu einem anderen Programm umgeleitet werden. Oder sogar einen Netzwerk-Socket, wenn Ihre Shell dies unterstützt.
Selbst die lächerlich kompliziertesten Pipelines sind nur Anweisungen an die Shell, wie diese drei Dateihandles verbunden werden, bevor das Programm ausgeführt wird.
(HINWEIS: Einige Programme verhalten sich anders, wenn eines davon an ein Terminal angeschlossen ist. Bei interaktiver Verwendung ist dies jedoch normalerweise benutzerfreundlicher. Wechselt beispielsweise ls
zur einspaltigen Ausgabe und zu keiner Farbe, wenn stdout nicht a ist Terminal - das ist normalerweise das, was Sie möchten, wenn Sie es an ein anderes Programm übergeben möchten. Einige Programme behandeln die Eingabeaufforderung anders, wenn stdin kein Terminal ist. Und so weiter.)