Python subprocess readlines() Hangs Issue
Strim fail dan mencetak output baris demi baris boleh dicapai menggunakan pelbagai kaedah. Walau bagaimanapun, menggunakan subproses dengan readlines() boleh membawa kepada isu hang.
Pertimbangkan skrip Python "main.py" yang direka untuk menstrim fail Ruby "ruby_sleep.rb" dan mencetak outputnya.
import pty import os from subprocess import Popen, PIPE, STDOUT file_path = '/path/to/ruby_sleep.rb' command = ' '.join(["ruby", file_path]) master, slave = pty.openpty() proc = Popen(command, bufsize=0, shell=True, stdout=slave, stderr=slave, close_fds=True) stdout = os.fdopen(master, 'r', 0) while proc.poll() is None: data = stdout.readline() if data != "": print(data) else: break print("This line is never reached")
Melaksanakan ini skrip menstrim keluaran Ruby seperti yang dijangkakan, tetapi kaedah readline() tergantung selama-lamanya, menyebabkan rentetan "Barisan ini tidak pernah dicapai" tidak pernah dicetak.
Pelbagai penyelesaian telah dicadangkan untuk menangani isu hang ini:
Stdbuf mendayakan penimbalan talian dalam mod bukan interaktif.
from subprocess import Popen, PIPE, STDOUT 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()
Pexpect boleh digunakan untuk kawalan berasaskan talian.
import pexpect pexpect.run("ruby ruby_sleep.rb", logfile=sys.stdout)
PTY membolehkan menyediakan tty untuk mendayakan penimbal talian pada bahagian Ruby.
import os import pty from subprocess import Popen, STDOUT master_fd, slave_fd = pty.openpty() proc = Popen(['ruby', 'ruby_sleep.rb'], stdin=slave_fd, stdout=slave_fd, stderr=STDOUT, close_fds=True) os.close(slave_fd) 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 Mengapakah `subprocess.Popen` Python dengan `readlines()` Hang, dan Bagaimana Saya Boleh Membetulkannya?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!