Frage

Wenn dies mein Subprozess ist:

import time, sys
for i in range(200):
    sys.stdout.write( 'reading %i\n'%i )
    time.sleep(.02)

Und dies ist das Skript, das die Ausgabe des Subprozesses steuert und verändert:

import subprocess, time, sys

print 'starting'

proc = subprocess.Popen(
    'c:/test_apps/testcr.py',
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE  )

print 'process created'

while True:
    #next_line = proc.communicate()[0]
    next_line = proc.stdout.readline()
    if next_line == '' and proc.poll() != None:
        break
    sys.stdout.write(next_line)
    sys.stdout.flush()

print 'done'

Warum ist readline und communicate Warten, bis der Vorgang abgelaufen ist? Gibt es eine einfache Möglichkeit, die Subprozess-Stdout-Echtzeit zu übergeben (und zu ändern)?

Übrigens habe ich gesehen Dies, aber ich brauche nicht die Protokollierungsfunktionen (und ich habe nicht die Mühe gemacht, viel davon zu verstehen).

Ich bin unter Windows XP.

War es hilfreich?

Lösung

Wie Charles bereits erwähnt, ist das Problem ein Puffer. Ich bin zu einem ähnlichen Problem gelaufen, als ich einige Module für SNMPD geschrieben habe, und löste es, indem ich STDOut durch eine automatische Flushing-Version ersetzt habe.

Ich habe den folgenden Code verwendet, der von einigen Beiträgen zu Activestate inspiriert wurde:

class FlushFile(object):
    """Write-only flushing wrapper for file-type objects."""
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

# Replace stdout with an automatically flushing version
sys.stdout = FlushFile(sys.__stdout__)

Andere Tipps

Die Prozessausgabe wird gepuffert. Auf mehr Unixy -Betriebssystemen (oder Cygwin), die pexect Das Modul ist verfügbar, wodurch alle notwendigen Beschwörungen rezitiert werden, um pufferungsbezogene Probleme zu vermeiden. Diese Beschwörungen erfordern jedoch eine Arbeit Pty -Modul, das nicht bei nativen (nicht-cygwin) Win32-Python-Builds erhältlich ist.

In dem Beispielfall, in dem Sie den Subprozess steuern, können Sie ihn einfach anrufen lassen sys.stdout.flush() Bei Bedarf - aber für willkürliche Unterprozesse ist diese Option nicht verfügbar.

Siehe auch Die Frage "Warum nicht einfach ein Rohr verwenden (popen ())?" in den pexpect faq.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top