In typischer UNIX-Manier read(2)
gibt 0 Bytes zurück, um das Dateiende anzuzeigen, was bedeuten kann:
- Es gibt keine Bytes mehr in einer Datei
- Das andere Ende eines Sockets hat die Verbindung beendet
- Der Schreiber hat eine Pipe geschlossen
In Ihrem Fall fifo.read()
gibt einen leeren String zurück, weil der Writer seinen Dateideskriptor geschlossen hat.
Sie sollten diesen Fall erkennen und aus Ihrer Schleife ausbrechen:
reader.py :
import os
import errno
FIFO = 'mypipe'
try:
os.mkfifo(FIFO)
except OSError as oe:
if oe.errno != errno.EEXIST:
raise
print("Opening FIFO...")
with open(FIFO) as fifo:
print("FIFO opened")
while True:
data = fifo.read()
if len(data) == 0:
print("Writer closed")
break
print('Read: "{0}"'.format(data))
Beispielsitzung
Terminal 1 :
$ python reader.py
Opening FIFO...
<blocks>
Terminal 2 :
$ echo -n 'hello' > mypipe
Terminal 1 :
FIFO opened
Read: "hello"
Writer closed
$
Update 1 – Kontinuierlich wieder öffnen
Sie geben an, dass Sie weiterhin auf Schreibvorgänge in der Pipe lauschen möchten, vermutlich sogar nachdem ein Schreiber geschlossen hat.
Um dies effizient zu tun, können (und sollten) Sie sich die Tatsache zunutze machen, dass
Normalerweise werden die FIFO-Blöcke geöffnet, bis das andere Ende ebenfalls geöffnet ist.
Hier füge ich eine weitere Schleife um open
hinzu und die read
Schleife. Auf diese Weise versucht der Code, sobald die Pipe geschlossen ist, sie erneut zu öffnen, was blockiert, bis ein anderer Schreiber die Pipe öffnet:
import os
import errno
FIFO = 'mypipe'
try:
os.mkfifo(FIFO)
except OSError as oe:
if oe.errno != errno.EEXIST:
raise
while True:
print("Opening FIFO...")
with open(FIFO) as fifo:
print("FIFO opened")
while True:
data = fifo.read()
if len(data) == 0:
print("Writer closed")
break
print('Read: "{0}"'.format(data))
Terminal 1 :
$ python reader.py
Opening FIFO...
<blocks>
Terminal 2 :
$ echo -n 'hello' > mypipe
Terminal 1 :
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
Terminal 2 :
$ echo -n 'hello' > mypipe
Terminal 1 :
FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>
... und so weiter.
Sie können mehr erfahren, indem Sie man
lesen Seite für Rohre:
- PIPE(7) - Handbuch für Linux-Programmierer
- FIFO(7) - Handbuch für Linux-Programmierer
(Jahre später) Wenn ich den Anwendungsfall des OP mit for ... in ...
verstehe macht genau das, was gewünscht wird:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
for line in fifo:
print(line)
Dieses Programm wartet geduldig auf Eingaben vom Fifo, bis diese bereitgestellt werden, und gibt sie dann auf dem Bildschirm aus. In der Zwischenzeit wird keine CPU verwendet.
Dies ist auch der idiomatischere Weg in Python, daher würde ich es eher empfehlen, als read() direkt zu verwenden.
Wenn die Client-Seite, die in das FIFO schreibt, schließt, endet die for-Schleife und das Programm wird beendet. Wenn Sie möchten, dass es das Fifo erneut öffnet, um darauf zu warten, dass der nächste Client es öffnet, können Sie den for
eingeben Abschnitt in eine While-Schleife:
import os
FIFO = 'myfifo'
os.mkfifo(FIFO)
while True:
with open(FIFO) as fifo:
for line in fifo:
print(line)
Dies wird das Fifo erneut öffnen und wie gewohnt warten.