suchen
HeimBackend-EntwicklungPython-TutorialWarum bleibt „subprocess.Popen' mit „readline()' hängen, wenn aus einem Ruby-Skript gelesen wird, und wie kann das behoben werden?

Why does `subprocess.Popen` with `readline()` hang when reading from a Ruby script, and how can this be fixed?

Python-Subprozess readlines() hängt

Problem:

Beim Lesen der Ausgabe eines Ruby-Skripts mit subprocess.Popen und readline() im Streaming-Modus, readline() bleibt auf unbestimmte Zeit und nie hängen kehrt zurück.

Hintergrund:

Das Ziel besteht darin, die Ausgabe einer Ruby-Datei Zeile für Zeile zu streamen und sie zu drucken, ohne die gesamte Ausgabe zu puffern.

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

Das ruby_sleep.rb-Skript gibt eine einfache Nachricht mit einer Dauer von 2 Sekunden aus Verzögerung:

puts "hello"

sleep 2

puts "goodbye!"

Grundursache:

readline() bleibt hängen, da das Ruby-Skript Daten ohne Abschlusszeilen (d. h. ohne Zeilenumbrüche) ausgibt. Dies führt dazu, dass readline() unbegrenzt darauf wartet, dass eine neue Zeile die Zeile vervollständigt.

Lösungen:

Je nach Plattformverfügbarkeit gibt es mehrere Lösungen:

  • Für Linux:

    Verwenden Sie pty aus der Standardbibliothek, um ein Pseudo-Terminal (tty) zu öffnen und die Zeilenpufferung auf der Ruby-Seite zu aktivieren, um sicherzustellen, dass jede Zeile mit einer neuen Zeile abgeschlossen wird.

    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!")
  • Für Linux-basierte Plattformen:

    Verwenden Sie pty aus der Standardbibliothek und wählen Sie aus, dass der Master-Dateideskriptor auf Aktivität überwacht werden soll, um sicherzustellen, dass die Daten vorhanden sind Nicht blockierend lesen.

    import os
    import pty
    import select
    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'],
                 stdout=slave_fd, stderr=STDOUT, close_fds=True)
    
    timeout = .04 # seconds
    while 1:
        ready, _, _ = select.select([master_fd], [], [], timeout)
        if ready:
            data = os.read(master_fd, 512)
            if not data:
                break
            print("got " + repr(data))
        elif proc.poll() is not None: # select timeout
            assert not select.select([master_fd], [], [], 0)[0] # detect race condition
            break # proc exited
    os.close(slave_fd) # can't do it sooner: it leads to errno.EIO error
    os.close(master_fd)
    proc.wait()
    
    print("This is reached!")
  • Plattformübergreifende Option:

    Verwenden Sie stdbuf, um die Zeilenpufferung im nicht interaktiven Modus zu aktivieren 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()

Diese Lösungen ermöglichen alle eine Zeilenpufferung auf der Ruby-Seite, um sicherzustellen, dass jede Zeile mit einem Zeilenumbruch abgeschlossen wird, damit readline() korrekt funktioniert.

Das obige ist der detaillierte Inhalt vonWarum bleibt „subprocess.Popen' mit „readline()' hängen, wenn aus einem Ruby-Skript gelesen wird, und wie kann das behoben werden?. 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
Wie schneiden Sie eine Python -Liste?Wie schneiden Sie eine Python -Liste?May 02, 2025 am 12:14 AM

SlicingPapythonListisDoneUsingthesyntaxlist [Start: Stop: Stufe] .here'Showitworks: 1) StartIndexoFtheFirstelementtoinclude.2) stopiStheIndexoFtheFirstelementtoexclude.3) StepisTheincrementBetweenelesfulFulForForforexcractioningPorporionsporporionsPorporionsporporesporsporsporsporsporsporsporsporsporionsporsPorsPorsPorsPorsporsporsporsporsporsporsAntionsporsporesporesporesporsPorsPorsporsPorsPorsporsporspors,

Was sind einige gängige Operationen, die an Numpy -Arrays ausgeführt werden können?Was sind einige gängige Operationen, die an Numpy -Arrays ausgeführt werden können?May 02, 2025 am 12:09 AM

Numpyallowsforvariousoperationssonarrays: 1) BasicarithmeticliKeaddition, Subtraktion, Multiplikation und Division; 2) AdvancedoperationssuchasmatrixMultiplication;

Wie werden Arrays in der Datenanalyse mit Python verwendet?Wie werden Arrays in der Datenanalyse mit Python verwendet?May 02, 2025 am 12:09 AM

Arraysinpython, insbesondere ThroughNumpyandpandas, areessentialfordataanalyse, öfterspeedandeffizienz.1) numpyarraysenableAnalysHandlingoflargedatasets und CompompexoperationslikemovingAverages.2) Pandasextendsnumpy'ScapaBilitiesWithDaTataforsForstruc

Wie vergleicht sich der Speicherpflichtiger einer Liste mit dem Speicher Fußabdruck eines Arrays in Python?Wie vergleicht sich der Speicherpflichtiger einer Liste mit dem Speicher Fußabdruck eines Arrays in Python?May 02, 2025 am 12:08 AM

ListsandNumPyarraysinPythonhavedifferentmemoryfootprints:listsaremoreflexiblebutlessmemory-efficient,whileNumPyarraysareoptimizedfornumericaldata.1)Listsstorereferencestoobjects,withoverheadaround64byteson64-bitsystems.2)NumPyarraysstoredatacontiguou

Wie behandeln Sie umgebungsspezifische Konfigurationen, wenn Sie ausführbare Python-Skripte bereitstellen?Wie behandeln Sie umgebungsspezifische Konfigurationen, wenn Sie ausführbare Python-Skripte bereitstellen?May 02, 2025 am 12:07 AM

TensurepythonscriptsBehavectelyAcrossdevelopment, Staging und Produktion, UsethesStrategien: 1) Umweltvariablenforsimplesettings, 2) configurationFilesForComplexSetups und 3) dynamikloadingForAdaptability.eachMethodofferiqueNefits und Requiresca

Wie schneiden Sie ein Python -Array?Wie schneiden Sie ein Python -Array?May 01, 2025 am 12:18 AM

Die grundlegende Syntax für die Python -Liste ist die Liste [START: STOP: STEP]. 1.Start ist der erste Elementindex, 2.Stop ist der erste Elementindex, und 3.Step bestimmt die Schrittgröße zwischen den Elementen. Scheiben werden nicht nur zum Extrahieren von Daten verwendet, sondern auch zum Ändern und Umkehrlisten.

Unter welchen Umständen könnte Listen besser abschneiden als Arrays?Unter welchen Umständen könnte Listen besser abschneiden als Arrays?May 01, 2025 am 12:06 AM

ListSoutPer -CharakterArraysin: 1) Dynamics und Dynamics und 3), 2) StoringHeterogenData und 3) MemoryefficiencyForSparsedata, ButmayHavesLightPerformanceCostIncustonTectorationOperationen.

Wie können Sie ein Python -Array in eine Python -Liste konvertieren?Wie können Sie ein Python -Array in eine Python -Liste konvertieren?May 01, 2025 am 12:05 AM

Toconvertapythonarraytoalist, Usethelist () constructororageneratorexpression.1) ImportThearrayModuleandCreateanarray.2) Uselist (arr) oder [xForxinarr] Toconvertittoalist in Betracht, überlegt Performance undMoryefficiencyForlargedatasets.

See all articles

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

MantisBT

MantisBT

Mantis ist ein einfach zu implementierendes webbasiertes Tool zur Fehlerverfolgung, das die Fehlerverfolgung von Produkten unterstützen soll. Es erfordert PHP, MySQL und einen Webserver. Schauen Sie sich unsere Demo- und Hosting-Services an.

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

SublimeText3 Linux neue Version

SublimeText3 Linux neue Version

SublimeText3 Linux neueste Version

SecLists

SecLists

SecLists ist der ultimative Begleiter für Sicherheitstester. Dabei handelt es sich um eine Sammlung verschiedener Arten von Listen, die häufig bei Sicherheitsbewertungen verwendet werden, an einem Ort. SecLists trägt dazu bei, Sicherheitstests effizienter und produktiver zu gestalten, indem es bequem alle Listen bereitstellt, die ein Sicherheitstester benötigen könnte. Zu den Listentypen gehören Benutzernamen, Passwörter, URLs, Fuzzing-Payloads, Muster für vertrauliche Daten, Web-Shells und mehr. Der Tester kann dieses Repository einfach auf einen neuen Testcomputer übertragen und hat dann Zugriff auf alle Arten von Listen, die er benötigt.