Rumah > pembangunan bahagian belakang > Tutorial Python > Mengapakah `subprocess.readlines()` Digantung Semasa Menstrim Fail Ruby dalam Python?

Mengapakah `subprocess.readlines()` Digantung Semasa Menstrim Fail Ruby dalam Python?

Mary-Kate Olsen
Lepaskan: 2024-12-06 12:59:15
asal
942 orang telah melayarinya

Why Does `subprocess.readlines()` Hang When Streaming a Ruby File in Python?

Python subprocess.readlines() hang

Masalah:

Dalam kod Python berikut , menggunakan subprocess.readlines() untuk menstrim fail Ruby menyebabkan program digantung selama-lamanya, menghalang kenyataan cetakan akhir daripada dilaksanakan:

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

file_path = '/Users/luciano/Desktop/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 is never reached!")
Salin selepas log masuk

Punca:

Isu di sini berpunca daripada penggunaan pty, yang bertujuan untuk pengendalian pseudo-terminal. Ini biasanya menyebabkan penimbalan baris pada bahagian Ruby, menyebabkan fungsi readline() menunggu selama-lamanya untuk aksara baris baharu.

Penyelesaian:

Terdapat beberapa pilihan untuk selesaikan isu ini:

1. Menggunakan pexpect:

pexpect mendayakan penimbalan talian dalam tetapan bukan interaktif:

import sys
import pexpect

pexpect.run("ruby ruby_sleep.rb", logfile=sys.stdout)
Salin selepas log masuk

2. Menggunakan stdbuf:

stdbuf boleh digunakan untuk 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()
Salin selepas log masuk

3. Menggunakan pty daripada pustaka standard:

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!")
Salin selepas log masuk

Atas ialah kandungan terperinci Mengapakah `subprocess.readlines()` Digantung Semasa Menstrim Fail Ruby dalam Python?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan