Wenn Sie das tun:
cat fifo
Angenommen, noch kein anderer Prozess hat das fifozum Schreiben geöffnet , catwird der open()Systemaufruf blockiert . Wenn ein anderer Prozess die Datei zum Schreiben öffnet, wird eine Pipe instanziiert und open()zurückgegeben. catruft read()eine Schleife auf und read()blockiert, bis ein anderer Prozess Daten in die Pipe schreibt.
catwird das Dateiende (eof) sehen, wenn alle anderen Schreibvorgänge ihren Dateideskriptor für das geschlossen haben fifo. An welchen Stellen catendet und das Rohr zerstört wird¹.
Sie müssten caterneut 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, tailbis ein Prozess eine Datei zum Schreiben geöffnet hat. Da Sie jedoch -n +1von Anfang an kein zu kopierendes tailElement 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 tailwird 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 inotifyund einiger Versionen von vermieden werden GNU tailmacht das dort). Das read()wird wieder mit eof (sofort, weshalb Sie zu 100% CPU sehen mit -s 0(die mit GNU tailMitteln 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 cates niemals eof darauf sehen wird (es instanziiert auch die Pipe sofort, selbst wenn es keinen anderen Prozess gibt, der das fifozum 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 fifoSchreiben ö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 filewü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 fileeiner 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 catBeenden und Schließen des Leseendes der Pipe, gibt es tatsächlich ein kleines Fenster, in dem ein Prozess das fifozum erneuten Schreiben öffnen könnte (und nicht blockiert werden kann, da es noch ein Leseende gibt ). Wenn es dann etwas schreibt, nachdem es beendet catwurde und bevor ein anderer Prozess das fifozum Lesen öffnet , wird es mit einem SIGPIPE getötet.
tail -fbenötigen suchbare Eingaben. Das Verhalten vontail -f fifoist undefiniert. Wenntail -f -s 0 fifoauf einigen Systemen funktioniert, verlassen sich diese Systeme auf nicht standardmäßiges Verhalten.