GNU/Linux >> Belajar Linux >  >> Linux

Python dibaca bernama PIPA

Dalam gaya khas UNIX, read(2) mengembalikan 0 byte untuk menunjukkan akhir file yang dapat berarti:

  • Tidak ada lagi byte dalam file
  • Ujung soket yang lain telah mematikan koneksi
  • Penulis telah menutup pipa

Dalam kasus Anda, fifo.read() mengembalikan string kosong, karena penulis telah menutup deskriptor filenya.

Anda harus mendeteksi kasus itu dan keluar dari lingkaran Anda:

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

Sesi contoh

Terminal 1 :

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

Terminal 2 :

$ echo -n 'hello' > mypipe 

Terminal 1 :

FIFO opened
Read: "hello"
Writer closed
$ 

Perbarui 1 - Buka kembali terus-menerus

Anda menunjukkan bahwa Anda ingin terus mendengarkan tulisan di pipa, mungkin bahkan setelah penulis tutup.

Untuk melakukan ini secara efisien, Anda dapat (dan harus) memanfaatkan fakta bahwa

Biasanya, membuka blok FIFO hingga ujung lainnya juga terbuka.

Di sini, saya menambahkan loop lain di sekitar open dan read lingkaran. Dengan cara ini, setelah pipa ditutup, kode akan mencoba membukanya kembali, yang akan memblokir hingga penulis lain membuka pipa:

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>

... dan seterusnya.

Anda dapat mempelajari lebih lanjut dengan membaca man halaman untuk pipa:

  • PIPE(7) - Panduan Pemrogram Linux
  • FIFO(7) - Panduan Pemrogram Linux

(Bertahun-tahun kemudian) Jika saya memahami kasus penggunaan OP menggunakan for ... in ... melakukan apa yang diinginkan:

import os

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

Program ini dengan sabar menunggu input dari fifo hingga tersedia, lalu mencetaknya di layar. Sementara itu, tidak ada CPU yang digunakan.

Ini juga cara yang lebih idiomatis di Python, jadi saya akan merekomendasikannya daripada menggunakan read() secara langsung.

Jika sisi klien menulis ke fifo ditutup, for loop berakhir dan program berhenti. Jika Anda ingin membuka kembali fifo untuk menunggu klien berikutnya membukanya, Anda dapat meletakkan for bagian menjadi while loop:

import os

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

Ini akan membuka kembali fifo dan menunggu seperti biasa.


Linux
  1. Cara Menggunakan Pipes dan Named Pipes di Linux (dengan Contoh)

  2. Membaca Terus Menerus Dari Pipa Bernama (cat Atau Ekor -f)?

  3. Tujuan Menggunakan Fifo Vs File Sementara Atau Pipa?

  1. Python dalam mode mentah stdin print menambahkan spasi

  2. Kesalahan impor tidak ada modul bernama zlib (brew diinstal python)

  3. Mengapa saya sepertinya kehilangan data menggunakan konstruksi pipa bash ini?

  1. Perintah Preug – SyntaxError:Tanda kurung hilang saat memanggil 'print' – Solusi

  2. ModuleNotFoundError:Tidak ada modul bernama 'IPython' [Fix]

  3. Memahami Jika?