Verarbeiten von Nachrichten aus einem unterkleideten Prozess gründlich Stderr und Stdout mit Python

StackOverflow https://stackoverflow.com/questions/4805576

Frage

Mein Python -Code erzeugt den Kinderprozess und druckt Nachrichten sowohl stdout als auch stderr aus. Ich muss sie anders drucken.

Ich habe den folgenden Code, um den Kinderprozess hervorzubringen und das StDout -Ergebnis daraus zu erhalten.

cmd = ["vsmake.exe", "-f"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for line in iter(p.stdout.readline, ''):
    print line,
    sys.stdout.flush()
    pass
p.wait()

Wie kann ich den Code ändern, um zu prüfen, ob der untergeordnete Prozess auch eine Nachricht über stderr ausdruiert?

HINZUGEFÜGT

Ich muss das Stderr und Stdout ausdrucken, sobald der Kinderprozess etwas ausdruckt. Und es ist eine Cross -Plattform -Implementierung, daher sollte es auf Mac/Linux/PC ausgeführt werden.

War es hilfreich?

Lösung

p = Popen(cmd, bufsize=1024,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
p.stdin.close()
print p.stdout.read() #This will print the standard output from the spawned process
print p.stderr.read() #This is what you need, error output <-----

Grundsätzlich wird der Fehlerausgang auf die umgeleitet stderr Rohr.

Wenn Sie rechtzeitig etwas realer brauchen. Ich meine, Zeilen gedruckt, sobald der hervorgebrachte Prozess etwas druckt stdout orStderr` dann kannst du so etwas wie:

def print_pipe(type_pipe,pipe):
    for line in iter(pipe.readline, ''):
         print "[%s] %s"%(type_pipe,line),

p = Popen(cmd, bufsize=1024,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)

t1 = Thread(target=print_pipe, args=("stdout",p.stdout,))
t1.start()
t2 = Thread(target=print_pipe, args=("stderr",p.stderr,))
t2.start()

#optionally you can join the threads to wait till p is done. This is avoidable but it 
# really depends on the application.
t1.join()
t2.join()

In diesem Fall drucken zwei Threads jedes Mal, wenn eine Zeile entweder geschrieben wird stdout oder stderr. Der Parameter type_pipe macht nur die Unterscheidung, wenn die Linien gedruckt werden, um zu wissen, ob sie von ihnen kommen stderr oder stdout.

Andere Tipps

Der einfachste Weg, um diese Plattform unabhängig zu machen, besteht darin, Threads (leider) zu verwenden. Hier ist ein Beispielcode:

def redirect_to_stdout(stream):
    for line in stream:
        sys.stdout.write(line)
        sys.stdout.flush()

cmd = ["vsmake.exe", "-f"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stderr_thread = threading.Thread(target=redirect_to_stdout, args=(p.stderr,))
stderr_thread.start()
redirect_to_stdout(p.stdout)
p.wait()
stderr_thread.join()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top