GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Python lesen mit dem Namen PIPE

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.


Linux
  1. Preug-Befehl – ​​SyntaxError:Fehlende Klammern beim Aufruf von „print“ – Lösung

  2. ModuleNotFoundError:Kein Modul namens „IPython“ [Fix]

  3. Wenns verstehen?

  4. Kontinuierliches Lesen von Named Pipe (Katze oder Schwanz -f)?

  5. Was benötige ich, um Microsoft Access-Datenbanken mit Python zu lesen?

Eine Einführung in Pipes und Named Pipes in Linux

Python if..else-Anweisung

Rohr B nach D? – A &&B || C | D?

O_RDWR auf Named Pipes mit poll()

So lesen Sie die Audiolautstärke des Echtzeitmikrofons in Python und ffmpeg oder ähnlichem

/etc/motd wird bei Named Pipe nicht angezeigt?