GNU/Linux >> Tutoriales Linux >  >> Linux

Python leído llamado PIPE

Al estilo típico de UNIX, read(2) devuelve 0 bytes para indicar el final del archivo, lo que puede significar:

  • No hay más bytes en un archivo
  • El otro extremo de un enchufe ha cerrado la conexión
  • El escritor ha cerrado una tubería

En tu caso, fifo.read() está devolviendo una cadena vacía, porque el escritor ha cerrado su descriptor de archivo.

Deberías detectar ese caso y salir de tu ciclo:

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

Sesión de ejemplo

Terminal 1 :

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

Terminal 2 :

$ echo -n 'hello' > mypipe 

Terminal 1 :

FIFO opened
Read: "hello"
Writer closed
$ 

Actualización 1:reapertura continua

Indica que desea seguir escuchando las escrituras en la canalización, presumiblemente incluso después de que un escritor haya cerrado.

Para hacer esto de manera eficiente, puede (y debe) aprovechar el hecho de que

Normalmente, se abren los bloques FIFO hasta que se abre también el otro extremo.

Aquí, agrego otro bucle alrededor de open y el read círculo. De esta manera, una vez que se cierre la tubería, el código intentará volver a abrirla, lo que bloqueará hasta que otro escritor abra la tubería:

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>

... y así sucesivamente.

Puede obtener más información leyendo el man página para tuberías:

  • PIPE(7) - Manual del programador de Linux
  • FIFO(7) - Manual del programador de Linux

(Años después) Si entiendo el caso de uso del OP usando for ... in ... hace exactamente lo que se desea:

import os

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

Este programa espera pacientemente la entrada del fifo hasta que se proporciona, luego lo imprime en la pantalla. Mientras tanto, no se utiliza ninguna CPU.

Esta es también la forma más idiomática en Python, por lo que la recomendaría en lugar de usar read() directamente.

Si el lado del cliente que escribe en el fifo se cierra, el bucle for finaliza y el programa se cierra. Si quisieras que volviera a abrir el fifo para esperar a que el próximo cliente lo abra puedes poner el for sección en un ciclo while:

import os

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

Esto reabrirá el fifo y esperará como de costumbre.


Linux
  1. ¿Lectura continua de tubería con nombre (cat o Tail -f)?

  2. ¿Qué necesito para leer bases de datos de Microsoft Access usando Python?

  3. Leer valores en una variable de shell desde una tubería

  4. Ejemplo de uso de canalizaciones con nombre en Linux Bash

  5. Canalizar la salida a la función bash

Una introducción a las canalizaciones y canalizaciones con nombre en Linux

Declaración de Python if..else

Tubería B a D? – A &&B || C | ¿D?

Cómo leer el volumen de audio del micrófono en tiempo real en python y ffmpeg o similar

/etc/motd no se muestra cuando hay una canalización con nombre?

¿Por qué parece que pierdo datos usando esta construcción de tubería bash?