Heim >Backend-Entwicklung >Python-Tutorial >Warum bleibt „subprocess.readlines()' hängen, wenn eine Ruby-Datei in Python gestreamt wird?

Warum bleibt „subprocess.readlines()' hängen, wenn eine Ruby-Datei in Python gestreamt wird?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-06 12:59:15927Durchsuche

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

Python subprocess.readlines() hängt

Problem:

Im folgenden Python-Code Wenn Sie subprocess.readlines() zum Streamen einer Ruby-Datei verwenden, bleibt das Programm auf unbestimmte Zeit hängen, sodass die endgültige Druckanweisung nicht ausgeführt werden kann ausgeführt:

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

Ursache:

Das Problem hier ergibt sich aus der Verwendung von pty, das für die Pseudo-Terminal-Verarbeitung gedacht ist. Dies führt normalerweise zu einer Zeilenpufferung auf der Ruby-Seite, was dazu führt, dass die Funktion readline() unbegrenzt auf ein Zeilenumbruchzeichen wartet.

Lösungen:

Es gibt mehrere Optionen dazu Beheben Sie dieses Problem:

1. Die Verwendung von pexpect:

pexpect ermöglicht die Zeilenpufferung in einer nicht interaktiven Umgebung:

import sys
import pexpect

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

2. Mit stdbuf:

stdbuf kann verwendet werden, um die Zeilenpufferung im nicht-interaktiven Modus zu aktivieren:

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

3. Verwenden von pty aus der Standardbibliothek:

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

Das obige ist der detaillierte Inhalt vonWarum bleibt „subprocess.readlines()' hängen, wenn eine Ruby-Datei in Python gestreamt wird?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn