Heim >Backend-Entwicklung >Python-Tutorial >Warum bleibt Pythons „subprocess.readlines()' hängen, wenn die Ruby-Ausgabe gestreamt wird, und wie kann ich das Problem beheben?

Warum bleibt Pythons „subprocess.readlines()' hängen, wenn die Ruby-Ausgabe gestreamt wird, und wie kann ich das Problem beheben?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-05 16:32:11826Durchsuche

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

Python-Subprozess Readlines() hängt

Problemstellung:

Beim Versuch, a zu streamen Ruby-Datei Zeile für Zeile in Python mithilfe des Subprocess-Moduls, der Aufruf von readlines() blockiert auf unbestimmte Zeit und verhindert so weitere Ausführung.

Ursache:

Dieses Problem kann auftreten, wenn das pty-Modul auf einem Nicht-Linux-Betriebssystem verwendet wird, um ein Pseudo-Terminal zu simulieren. pty ist eine Linux-spezifische Bibliothek und ihr Verhalten auf anderen Systemen kann nicht garantiert werden.

Lösungen:

1. Verwenden Sie Pexpect:

Pexpect ist eine plattformübergreifende Bibliothek zur Automatisierung interaktiver Anwendungen. Es bietet eine High-Level-Schnittstelle zum Senden und Empfangen von Daten über ein Pseudo-Terminal.

import pexpect

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

2. Verwenden Sie Stdbuf:

Stdbuf kann verwendet werden, um die Zeilenpufferung im nicht interaktiven Modus zu aktivieren, sodass die Ausgabe in jeder Zeile geleert werden kann.

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 Sie Pty aus der Standardbibliothek (für 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!")

Das obige ist der detaillierte Inhalt vonWarum bleibt Pythons „subprocess.readlines()' hängen, wenn die Ruby-Ausgabe gestreamt wird, und wie kann ich das Problem beheben?. 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