Wenn sich in einer benannten Pipe nichts befindet und ich Folgendes tue:
cat my_named_pipe
es wird gewartet, bis Daten eintreffen. Gibt es ein Flag, mit dem ich sofort beenden kann, wenn keine Daten zum Lesen vorhanden sind? Oder vielleicht einen anderen Befehl als cat, den ich verwenden kann?
Ich habe auch versucht:
read val < "$my_named_pipe";
aber dies wartet auch auf den nächsten Datenblock – ich möchte nicht warten, wenn der FIFO leer ist.
Antwort1
Um ein Hängenbleiben bei Abwesenheit eines Writers zu verhindern cat
(in diesem Fall hängt das Öffnen des FIFO und nicht das Lesen daraus), können Sie Folgendes tun:
cat 0<> "$my_named_pipe" <"$my_named_pipe"
Die erste Umleitung öffnet im Lese- und Schreibmodus, was auf den meisten Systemen nicht blockiert und die Pipe instanziiert, auch wenn es weder einen Schreiber noch einen Leser gibt. Dann würde das zweite Öffnen (diesmal schreibgeschützt) nicht blockieren, da es jetzt mindestens einen Schreiber (sich selbst) gibt.
Dies 0
ist nur in neueren Versionen von ksh93 erforderlich, in denen der Standard-FD <>
von 0 auf 1 geändert wurde.
Außerdem ksh93
würde das in nicht funktionieren, wenn cat
die Shell eingebaut ist, wie wenn ksh93
aufgerufen wird, wenn /opt/ast/bin
vor /bin
in $PATH
oder nach einem Aufruf von steht , builtin cat
wie beim <"$my_named_pipe"
, (nehme ich an) speichert ksh93 das vorherige Ziel von stdin in einem separaten Dateideskriptor, der die Pipe offen halten würde. Sie können das umgehen, indem Sie stattdessen Folgendes schreiben:
cat 3<> "$my_named_pipe" <"$my_named_pipe" 3<&-
(wodurch Ihrer Meinung nach auch die Absicht klarer zum Ausdruck kommt)
Beachten Sie, dass dadurch <>
auf der Pipe auch andere Leser für das FIFO freigeschaltet werden.
Wenn es einige Schreiber gäbe, cat
müssten diese trotzdem deren gesamte Ausgabe lesen und warten, bis sie ihr Ende der Pipe geschlossen haben. Sie könnten die Pipe im nicht blockierenden Modus öffnen, wie bei GNU dd
:
dd bs=64k if="$my_named_pipe" iflag=nonblock status=noxfer
Das liest nur aus der Pipe, solange Daten darin sind, und beendet mit einem
dd: error reading 'fifo': Resource temporarily unavailable
Fehler, wenn es keine mehr gibt, und andere Leser nicht freischalten, aber das bedeutet, dass Sie einige der Ausgaben der Writer verpassen könnten, wenn diese langsamer in die Pipe schreiben als Sie ( dd
) beim Lesen.
Ein anderer Ansatz könnte darin bestehen, ein Timeout einzurichten, wenn über einen längeren Zeitraum keine Eingabe erfolgt ist. Dies kann beispielsweise durch die Verwendung socat
der -T
Option erfolgen:
socat -u -T1 - - 0<> "$my_named_pipe" <"$my_named_pipe"
Dies würde beendet, wenn innerhalb einer Sekunde nichts aus der Leitung gekommen wäre.
Antwort2
Etwas ganz Einfaches wäre, cat
sofort nach dem Lesen des FIFOs zu beenden, unabhängig davon, ob Daten vorhanden sind oder nicht. Dies könnte man mit tun timeout
, und zwar wie folgt:
timeout 2 cat my_named_pipe
Oben timeout
wird zwei Sekunden gewartet, bevor die Beendigung von cat erzwungen wird. Wenn beim Ausführen etwas in der benannten Pipe gepuffert ist cat
, wird es auf stdout gedruckt.
Vielleicht nicht die sauberste Lösung, aber sie erfüllt ihren Zweck.
Ich hoffe es hilft.