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
Freigeben: 2024-12-06 12:59:15
Original
907 Leute haben es durchsucht

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!")
Nach dem Login kopieren

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)
Nach dem Login kopieren

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()
Nach dem Login kopieren

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!")
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage