Lassen Sie uns nochmal unser Beispiel über die Umleitung der
Ein-/Ausgabe betrachten. Dies stellt eine gute Verdeutlichung des
Konzepts der Verweise dar. Wenn Sie eine solche Umleitung in einer
Kommandozeile verwenden, erzeugt die Shell diese für Sie und
verhält sich so, dass der Befehl vor der Umleitung dort hinein schreibt
und derjenige danach von ihr liest. Dadurch wird deutlich, dass sie
sich wie eine Röhre (engl. pipe,
pipeline) verhält. Alle Röhren, egal ob nun anonyme
(wie diejenigen, die von der Shell angelegt werde) oder benannte
(s.unten), verhalten sich wie FIFOs (First In,
First Out, engl. für ,,Was zuerst reinkommt, geht
auch zuerst wieder raus``). Wir haben schon einige Beispiele
gesehen, wie man solche Röhren in einer Shell benutzen kann.
Lassen Sie uns dennoch zum Zwecke der Demonstration ein weiteres
einführen:
$ ls -d /proc/[0-9] | head -5
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/ |
Eines, was Sie nicht in diesem Beispiel erkennen werden (weil es zu
schnell dafür abläuft) ist, dass das Schreiben in eine solche Umleitung
blockierend ist. Das heißt das schreibende Kommando ls ist
solange blockiert bis ein Prozess am anderen Ende der Röhre liest. Um
dies zu verdeutlichen, können Sie auch benannte Umleitungen erzeugen,
die, im Gegensatz zu solchen der Shell referenziert
werden.[1] Der Befehl zum Erzeugen solcher
Umleitungen lautet: mkfifo
$ mkfifo eine_pipe
$ ls -il
total 0
169 prw-rw-r-- 1 franz franz 0 Dez 10 14:12 eine_pipe|
#
# Hier ist der Verweise-Zähler 1 und die Ausgabe zeigt an,
# dass es sich bei der Datei um eine pipe ("p") handelt.
#
# Sie können hier ebenfalls ln verwenden:
#
$ ln eine_pipe die_selbe_pipe
$ ls -il
total 0
169 prw-rw-r-- 2 franz franz 0 Dez 10 15:37 eine_pipe|
169 prw-rw-r-- 2 franz franz 0 Dez 10 15:37 die_selbe_pipe|
$ ls -d /proc/[0-9] >eine_pipe
#
# Der Prozess ist blockiert, da am anderen Ende kein Leser ist.
# Drücken Sie Strg-z, um den Prozess zu beenden...
#
zsh: 3452 suspended ls -d /proc/[0-9] > eine_pipe
#
# ...Dann verschieben Sie ihn in den Hintergrund:
#
$ bg
[1] + continued ls -d /proc/[0-9] > eine_pipe
#
# lesen Sie jetzt von der Pipe...
#
$ head -6 <die_selbe_pipe
#
# ...der Schreib-Prozess wird beendet
#
[1] + 3452 done ls -d /proc/[0-9] > eine_pipe
/proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
# |
Genau wie das Schreiben, ist auch das Lesen blockierend. Wenn wir die
obigen Kommandos in umgekehrter Reihenfolge starten, erkennen wir, das
head blockiert ist und auf einen Prozess wartet, der ihm
etwas zu lesen gibt:
$ head -5 <eine_pipe
#
# Programm blockiert, beenden Sie es mit: Strg-z
#
zsh: 741 suspended head -5 < eine_pipe
#
# Stellen Sie es in den Hintergrund ...
#
$ bg
[1] + continued head -5 < eine_pipe
#
# ... und geben Sie ihm etwas zu essen ... :)
#
$ ls -d /proc/[0-9] >die_selbe_pipe
$ /proc/1/
/proc/2/
/proc/3/
/proc/4/
/proc/5/
[1] + 741 done head -5 < eine_pipe
$ |
Sie können im obigen Beispiel auch einen unerwünschten Effekt
beobachten: Das Kommando ls hat sich schon beendet, bevor der
Befehl head gestartet wurde. Daher erhielten Sie sofort wieder
die Eingabeaufforderung, ohne eine Ausgabe von head zu erhalten.
Diese folgt allerdings wenig später.