Wenn Sie das tun:
cat fifo
Angenommen, noch kein anderer Prozess hat das fifo
zum Schreiben geöffnet , cat
wird der open()
Systemaufruf blockiert . Wenn ein anderer Prozess die Datei zum Schreiben öffnet, wird eine Pipe instanziiert und open()
zurückgegeben. cat
ruft read()
eine Schleife auf und read()
blockiert, bis ein anderer Prozess Daten in die Pipe schreibt.
cat
wird das Dateiende (eof) sehen, wenn alle anderen Schreibvorgänge ihren Dateideskriptor für das geschlossen haben fifo
. An welchen Stellen cat
endet und das Rohr zerstört wird¹.
Sie müssten cat
erneut ausführen , um zu lesen, was danach in die fifo
(aber über eine andere Pipe-Instanz) geschrieben wird.
Im:
tail -f file
Warten Sie cat
, tail
bis ein Prozess eine Datei zum Schreiben geöffnet hat. Da Sie jedoch -n +1
von Anfang an kein zu kopierendes tail
Element angegeben haben, müssen Sie bis eof warten, um herauszufinden, was die letzten 10 Zeilen waren, sodass Sie nichts sehen, bis das Schreibende geschlossen ist.
Danach tail
wird das fd nicht für die Pipe geschlossen, was bedeutet, dass die Pipe-Instanz nicht zerstört wird, und es wird weiterhin versucht, jede Sekunde aus der Pipe zu lesen (unter Linux kann das Abrufen durch die Verwendung von inotify
und einiger Versionen von vermieden werden GNU tail
macht das dort). Das read()
wird wieder mit eof (sofort, weshalb Sie zu 100% CPU sehen mit -s 0
(die mit GNU tail
Mitteln nicht zwischen warten read()
s statt für eine Sekunde des Wartens)) , bis ein anderen Prozess die Datei erneut zum Schreiben öffnet.
Hier möchten Sie möglicherweise stattdessen verwenden cat
, aber stellen Sie sicher, dass die Pipe-Instanz nach der Instanziierung immer verfügbar bleibt. Dafür können Sie auf den meisten Systemen Folgendes tun:
cat 0<> fifo # the 0 is needed for recent versions of ksh93 where the
# default fd changed from 0 to 1 for the <> operator
cat
's stdin ist sowohl zum Lesen als auch zum Schreiben geöffnet, was bedeutet, dass cat
es niemals eof darauf sehen wird (es instanziiert auch die Pipe sofort, selbst wenn es keinen anderen Prozess gibt, der das fifo
zum Schreiben öffnet ).
Auf Systemen, auf denen dies nicht funktioniert, können Sie stattdessen Folgendes tun:
cat < fifo 3> fifo
Auf diese Weise wird, sobald ein anderer Prozess das fifo
Schreiben öffnet , der erste schreibgeschützte Vorgang open()
zurückgegeben. An diesem Punkt führt die Shell open()
vor dem Start den schreibgeschützten Vorgang aus cat
, wodurch verhindert wird, dass die Pipe jemals wieder zerstört wird.
Um es zusammenzufassen:
- im Vergleich dazu
cat file
würde es nach der ersten Runde nicht aufhören.
- im vergleich zu
tail -n +1 -f file
: es würde nicht read()
jede sekunde nach der ersten runde nutzlos machen , es würde niemals eof auf der einen instanz der pipe geben, es würde nicht bis zu einer sekundenverzögerung geben, wenn ein zweiter prozess die rohre zum schreiben nach der runde öffnet zuerst hat man es geschlossen.
- im Vergleich zu
tail -f file
. Darüber hinaus müsste es nicht warten, bis die erste Runde beendet ist, bevor etwas ausgegeben wird (nur die letzten 10 Zeilen).
- Im Vergleich zu
cat file
einer Schleife würde es nur eine Pipe-Instanz geben. Die in ¹ genannten Rennfenster würden vermieden.
¹ An diesem Punkt, zwischen dem letzten read()
, der eof anzeigt, und dem cat
Beenden und Schließen des Leseendes der Pipe, gibt es tatsächlich ein kleines Fenster, in dem ein Prozess das fifo
zum erneuten Schreiben öffnen könnte (und nicht blockiert werden kann, da es noch ein Leseende gibt ). Wenn es dann etwas schreibt, nachdem es beendet cat
wurde und bevor ein anderer Prozess das fifo
zum Lesen öffnet , wird es mit einem SIGPIPE getötet.
tail -f
benötigen suchbare Eingaben. Das Verhalten vontail -f fifo
ist undefiniert. Wenntail -f -s 0 fifo
auf einigen Systemen funktioniert, verlassen sich diese Systeme auf nicht standardmäßiges Verhalten.