Python-Unterprozess readlines() hängt Problem
Das Streamen einer Datei und das zeilenweise Drucken der Ausgabe können erreicht werden mit verschiedenen Methoden. Die Verwendung eines Unterprozesses mit readlines() kann jedoch zu Problemen mit dem Aufhängen führen.
Betrachten Sie das Python-Skript „main.py“, das zum Streamen einer Ruby-Datei „ruby_sleep.rb“ und entwickelt wurde druckt seine Ausgabe.
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")
Durch die Ausführung dieses Skripts wird die Ruby-Ausgabe gestreamt wie erwartet, aber die readline()-Methode bleibt auf unbestimmte Zeit hängen, was dazu führt, dass die Zeichenfolge „Diese Zeile wird nie erreicht“ nie gedruckt wird.
Es wurden verschiedene Lösungen vorgeschlagen, um dieses Problem zu beheben Problem:
Stdbuf ermöglicht die Zeilenpufferung im nicht-interaktiven Modus.
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 kann zur zeilenbasierten Steuerung verwendet werden.
import pexpect pexpect.run("ruby ruby_sleep.rb", logfile=sys.stdout)
PTY ermöglicht die Bereitstellung eines TTY, um die Zeilenpufferung auf der Ruby-Seite zu ermöglichen.
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!")
Das obige ist der detaillierte Inhalt vonWarum bleibt Pythons „subprocess.Popen' mit „readlines()' hängen und wie kann ich das beheben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!