GNU/Linux >> Linux Esercitazione >  >> Linux

Python legge denominato PIPE

In tipico stile UNIX, read(2) restituisce 0 byte per indicare la fine del file che può significare:

  • Non ci sono più byte in un file
  • L'altra estremità di un socket ha interrotto la connessione
  • Lo scrittore ha chiuso una pipa

Nel tuo caso, fifo.read() sta restituendo una stringa vuota, perché il writer ha chiuso il suo descrittore di file.

Dovresti rilevare quel caso e uscire dal tuo loop:

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))

Sessione di esempio

Terminale 1 :

$ python reader.py 
Opening FIFO...
<blocks>

Terminal 2 :

$ echo -n 'hello' > mypipe 

Terminale 1 :

FIFO opened
Read: "hello"
Writer closed
$ 

Aggiornamento 1 - Riapertura continua

Indichi che vuoi continuare ad ascoltare le scritture sulla pipa, presumibilmente anche dopo che uno scrittore ha chiuso.

Per farlo in modo efficiente, puoi (e dovresti) sfruttare il fatto che

Normalmente, l'apertura dei blocchi FIFO fino a quando non viene aperta anche l'altra estremità.

Qui, aggiungo un altro giro attorno a open e il read ciclo continuo. In questo modo, una volta chiusa la pipe, il codice tenterà di riaprirla, il che si bloccherà finché un altro writer non aprirà la pipe:

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))

Terminale 1 :

$ python reader.py 
Opening FIFO...
<blocks>

Terminal 2 :

$ echo -n 'hello' > mypipe 

Terminale 1 :

FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>

Terminal 2 :

$ echo -n 'hello' > mypipe 

Terminale 1 :

FIFO opened
Read: "hello"
Writer closed
Opening FIFO...
<blocks>

... e così via.

Puoi saperne di più leggendo il man pagina per pipe:

  • PIPE(7) - Manuale del programmatore Linux
  • FIFO(7) - Manuale del programmatore Linux

(Anni dopo) Se capisco il caso d'uso dell'OP usando for ... in ... fa esattamente ciò che si desidera:

import os

FIFO = 'myfifo'
os.mkfifo(FIFO)
with open(FIFO) as fifo:
    for line in fifo:
        print(line)

Questo programma attende pazientemente l'input dal fifo finché non viene fornito, quindi lo stampa sullo schermo. Nessuna CPU viene utilizzata nel frattempo.

Questo è anche il modo più idiomatico in Python, quindi lo consiglierei piuttosto che usare read() direttamente.

Se la scrittura lato client sul fifo si chiude, il ciclo for termina e il programma si chiude. Se vuoi che riapra il fifo per aspettare che il prossimo client lo apra puoi mettere il for section in un ciclo while:

import os

FIFO = 'myfifo'
os.mkfifo(FIFO)
while True:
    with open(FIFO) as fifo:
        for line in fifo:
            print(line)

Questo riaprirà il fifo e aspetterà come al solito.


Linux
  1. ModuleNotFoundError:nessun modulo denominato "IPython" [fissare]

  2. Capire se?

  3. Lo scopo dell'utilizzo di un Fifo contro un file temporaneo o una pipe?

  4. Legge i valori in una variabile di shell da una pipe

  5. Esempio di utilizzo di named pipe in Linux Bash

Un'introduzione alle pipe e alle named pipe in Linux

Python if..else Istruzione

Tubo da B a D? – A&&B || C | D?

Come leggere il volume audio del microfono in tempo reale in python e ffmpeg o simili

/etc/motd non viene visualizzato quando una named pipe?

Perché mi sembra di perdere dati usando questa costruzione di pipe bash?