GNU/Linux >> Znalost Linux >  >> Linux

Čtení v Pythonu s názvem PIPE

Typickým způsobem pro UNIX read(2) vrací 0 bajtů pro označení konce souboru, což může znamenat:

  • V souboru již nejsou žádné bajty
  • Druhý konec soketu ukončil připojení
  • Autor zavřel kanál

Ve vašem případě fifo.read() vrací prázdný řetězec, protože zapisovač uzavřel svůj deskriptor souboru.

Měli byste tento případ odhalit a opustit smyčku:

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

Příklad relace

Terminál 1 :

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

Terminál 2 :

$ echo -n 'hello' > mypipe 

Terminál 1 :

FIFO opened
Read: "hello"
Writer closed
$ 

Aktualizace 1 – průběžně znovu otevírat

Uvádíte, že chcete pokračovat v naslouchání zápisům na kanálu, pravděpodobně i poté, co zapisovač zavře.

Chcete-li to provést efektivně, můžete (a měli byste) využít skutečnosti, že

Normálně otevírání bloků FIFO, dokud se neotevře i druhý konec.

Zde přidávám další smyčku kolem open a read smyčka. Tímto způsobem, jakmile je roura uzavřena, kód se ji pokusí znovu otevřít, což bude blokováno, dokud ji neotevře jiný zapisovač:

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

Terminál 1 :

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

Terminál 2 :

$ echo -n 'hello' > mypipe 

Terminál 1 :

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

Terminál 2 :

$ echo -n 'hello' > mypipe 

Terminál 1 :

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

... a tak dále.

Více se můžete dozvědět přečtením man stránka pro potrubí:

  • PIPE(7) – Linux Programmer's Manual
  • FIFO(7) – Linux Programmer's Manual

(O několik let později) Pokud rozumím případu použití OP pomocí for ... in ... dělá přesně to, co je požadováno:

import os

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

Tento program trpělivě čeká na vstup z fifo, dokud není poskytnut, a poté jej vytiskne na obrazovku. Mezitím není použit žádný CPU.

Toto je také více idiomatický způsob v Pythonu, takže bych to doporučil spíše než přímo používat read().

Pokud se na straně klienta zapisující do fifo zavře, smyčka for se ukončí a program se ukončí. Pokud chcete, aby znovu otevřelo fifo a počkalo, až jej otevře další klient, můžete zadat for sekce do smyčky while:

import os

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

Toto znovu otevře fifo a počká jako obvykle.


Linux
  1. Nepřetržité čtení z pojmenované dýmky (kočka nebo ocas -f)?

  2. Číst hodnoty do proměnné shellu z kanálu

  3. Příklad použití pojmenovaných kanálů v Linux Bash

  1. Jak používat Pipes a Named Pipes v Linuxu (s příklady)

  2. Výstup potrubí do funkce bash

  3. Python v raw režimu standardní tisk přidává mezery

  1. Příkaz Preug – SyntaxError:Chybějící závorky ve volání „print“ – Řešení

  2. ModuleNotFoundError:Žádný modul s názvem „IPython“ [Oprava]

  3. Rozumět Ifs?