Rumah >pembangunan bahagian belakang >Tutorial Python >Mengapa `subprocess.readlines()` Python Bergantung Semasa Menstrim Output Ruby dan Bagaimana Saya Boleh Membetulkannya?

Mengapa `subprocess.readlines()` Python Bergantung Semasa Menstrim Output Ruby dan Bagaimana Saya Boleh Membetulkannya?

Patricia Arquette
Patricia Arquetteasal
2024-12-05 16:32:11818semak imbas

Why Does Python's `subprocess.readlines()` Hang When Streaming Ruby Output, and How Can I Fix It?

Python Subprocess Readlines() Hangs

Penyataan Masalah:

Apabila cuba menstrim Fail Ruby baris demi baris dalam Python menggunakan modul subproses, blok panggilan readlines(). selama-lamanya, menghalang pelaksanaan selanjutnya.

Punca:

Isu ini boleh timbul apabila menggunakan modul pty pada sistem pengendalian bukan Linux untuk mensimulasikan terminal pseudo. pty ialah perpustakaan khusus Linux dan kelakuannya pada sistem lain tidak dijamin.

Penyelesaian:

1. Gunakan Peexpect:

Pexpect ialah perpustakaan merentas platform yang direka untuk mengautomasikan aplikasi interaktif. Ia menyediakan antara muka peringkat tinggi untuk menghantar dan menerima data melalui terminal pseudo.

import pexpect

pexpect.run("ruby ruby_sleep.rb", logfile=sys.stdout)

2. Gunakan Stdbuf:

Stdbuf boleh digunakan untuk mendayakan penimbalan talian dalam mod bukan interaktif, membenarkan output dipadamkan pada setiap baris.

proc = Popen(['stdbuf', '-oL', 'ruby', 'ruby_sleep.rb'],
             bufsize=1, stdout=PIPE, stderr=STDOUT, close_fds=True)
for line in iter(proc.stdout.readline, b''):
    print(line)
proc.stdout.close()
proc.wait()

3. Gunakan Pty daripada Pustaka Standard (untuk Linux):

import errno
import os
import pty
from subprocess import Popen, STDOUT

master_fd, slave_fd = pty.openpty()  # provide tty to enable line-buffering on Ruby's side
proc = Popen(['ruby', 'ruby_sleep.rb'],
             stdin=slave_fd, stdout=slave_fd, stderr=STDOUT, close_fds=True)
os.close(slave_fd)
try:
    while 1:
        try:
            data = os.read(master_fd, 512)
        except OSError as e:
            if e.errno != errno.EIO:
                raise
            break  # EIO means EOF on some systems
        else:
            if not data:  # EOF
                break
            print('got ' + repr(data))
finally:
    os.close(master_fd)
    if proc.poll() is None:
        proc.kill()
    proc.wait()
print("This is reached!")

Atas ialah kandungan terperinci Mengapa `subprocess.readlines()` Python Bergantung Semasa Menstrim Output Ruby dan Bagaimana Saya Boleh Membetulkannya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn