2013-03-10 12 views
5

Ich möchte lesen, was während der Ausführung von einem Unterprozess in stderr geschrieben wird.Lesen stderr des Unterprozesses, während es

Wenn ich jedoch dieses Skript verwende, das ich geschrieben habe, scheint stderr nichts zu lesen, bis der Subprozess beendet ist.

#!/usr/bin/env python2 

import sys 
from subprocess import Popen, PIPE, STDOUT 

if len(sys.argv) < 2: 
    print "Please provide a command" 
    sys.exit(1) 

sub = Popen(sys.argv[1:], stdout=PIPE, stderr=STDOUT) 

for i, line in enumerate(sub.stdout): 
    sys.stdout.write("%d: %s" % (i, line)) 

edit:

Ok, habe ich jetzt näher gekommen. Wenn ich die Anzahl der zu lesenden Bytes festlege, wird die Pufferung aufgehoben.

#!/usr/bin/env python2 

import sys 
from subprocess import Popen, PIPE, STDOUT 

if len(sys.argv) < 2: 
    print "Please provide a command" 
    sys.exit(1) 

sub = Popen(sys.argv[1:], stdout=PIPE, stderr=STDOUT) 

i = 0 
while sub.poll() is None: 
    line = sub.stdout.read(64) 
    line.strip("\b") 
    sys.stdout.write("%d: %s\n" % (i, line)) 
    i += 1 

Snippet Ausgabe:

58: 86 q=21.0 size= 4541841kB time=00:00:22.08 bitrate=1685014.2kbi 
frame= 567 fps= 86 q=22.0 size= 4543667kB time=00:00:2 
frame= 621 fps= 87 q=20.0 sizs/s  
frame= 4545352kB time=00:00:26.11 bitrate=1425939.2kbits/s  
62: = 686 fps= 90 q=12.0 size= 4546970kB time=00:00:28.89 bitrate=1 
frame= 758 fps= 93 q=25.0 size= 4548534kB t 
frame= 794 fps= 92 bitrate=1168185.5kbits/s  
65: q=27.0 size= 4550901kB time=00:00:33.40 bitrate=1115897.0kbits/ 
frame= 827 fps= 91 q=27.0 size= 4552324kB time=00:00:34.7 
frame= 857 fps= 89 q=26.0 size= 
frame= 254kB time=00:00:36.12 bitrate=1032874.9kbits/s  
69: 892 fps= 88 q=25.0 size= 4556598kB time=00:00:37.36 bitrate=9988 
frame= 948 fps= 89 q=19.0 size= 4558565kB time= 
frame= 1006 fps= 90 q=19937320.4kbits/s  
72: .0 size= 4560139kB time=00:00:42.16 bitrate=885880.0kbits/s  
73: frame= 1060 fps= 91 q=19.0 size= 4561958kB time=00:00:44.49 bitr 
frame= 1122 fps= 93 q=18.0 size= 4563460 
frame= 1173 fps=0:47.08 bitrate=793898.4kbits/s 

Es sieht aus wie mein Problem ist jetzt, dass ffmpeg mit stdout Backspace Zeichen oder ähnlich zu Chaos verwendet. Ich bin mir nicht sicher, was hier passiert.

+0

Welchen Prozess verwenden Sie? Es wird höchstwahrscheinlich die Ausgabe gepuffert, wenn es mit einer Pipe verbunden ist. –

+0

Siehe [fanging stdout in Echtzeit von subprocess] (http://stackoverflow.com/q/1606795) –

+0

Der Prozess ist ffmpeg, ich versuche, die fps während der Konvertierung zu lesen – OregonTrail

Antwort

3

Ich empfehle, sh Modul zu verwenden. Es ist ein sehr schönes Stück Software, die Teilprozesse in Python umschließt und Ihnen ein pythonisches, schönes Interface gibt, das Sie lieben werden. Schau dir die docs an.

Wenn Sie PIPE für beide wirklich wollen auch nicht sh Modul verwenden communicate Methode von Popen

+0

Wer sagt, dass das OP kommuniziert? –

1

Sie sollten verwenden, müssen Sie communicate() nennen: Sie

sub = Popen(sys.argv[1:], stdout=PIPE, stderr=PIPE) 
output, error_output = sub.communicate() 

print 'OUTPUT:' 
print output 

print 'ERROR:' 
print error_output 
+0

Warum ist das? "Stderr" auf stdout umleiten ist in Ordnung, und nicht das Problem. –

+0

In diesem Fall ist es kein Problem. Im Allgemeinen möchten Sie möglicherweise trennen, um zu wissen, ob ein Fehler aufgetreten ist. Ich vermisste das fehlende 'communicate()', das notwendig ist, um das Problem des ursprünglichen Posters zu beheben. –