2013-03-10 29 views
5

Tôi muốn đọc những gì được viết cho stderr bởi một tiến trình con trong khi nó đang thực hiện.Đọc stderr của subprocess trong khi nó đang thực hiện

Tuy nhiên, khi tôi sử dụng tập lệnh này mà tôi đã viết, stderr dường như không có bất cứ điều gì để tôi đọc cho đến khi tiến trình con đã thoát.

#!/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)) 

chỉnh sửa:

Ok, tôi đã nhận được gần gũi hơn bây giờ. Nếu tôi chỉ định số byte để đọc nó vượt qua bộ đệm.

#!/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 sản lượng:

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 

Dường như vấn đề của tôi bây giờ là ffmpeg đó là sử dụng ký tự backspace hoặc tương tự để gây rối với stdout. Bạn không chắc chắn những gì đang xảy ra ở đây.

+0

Bạn đang sử dụng quy trình nào? Nó rất có thể đệm đầu ra của nó khi kết nối với một đường ống. –

+0

Xem [bắt stdout trong thời gian thực từ subprocess] (http://stackoverflow.com/q/1606795) –

+0

Quá trình này là ffmpeg, tôi đang cố gắng để đọc fps trong quá trình chuyển đổi – OregonTrail

Trả lời

3

Tôi đề nghị sử dụng mô-đun sh. Nó là phần mềm rất đẹp mà kết thúc tốt đẹp các quy trình con trong python và cung cấp cho bạn giao diện đẹp, bắt mắt mà bạn sẽ yêu thích. Nhìn vào số docs.

Nếu bạn thực sự không muốn sh module, sử dụng communicate phương pháp Popen

+0

Ai nói OP đang sử dụng giao tiếp? –

1

Bạn nên sử dụng PIPE cho cả hai, cũng có thể, bạn cần phải gọi communicate():

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

print 'OUTPUT:' 
print output 

print 'ERROR:' 
print error_output 
+0

Tại sao vậy? Việc chuyển hướng 'stderr' sang stdout là tốt, chứ không phải vấn đề. –

+0

Trong trường hợp này, nó không phải là một vấn đề. Nói chung, bạn có thể muốn tách chúng ra để biết nếu có bất kỳ lỗi nào xảy ra. Tôi đã không đề cập đến thiếu 'communication()', điều cần thiết để khắc phục vấn đề của poster ban đầu. –

1

Nếu subprocess doesn't use block-buffering sau đó bạn có thể thử:

for i, line in enumerate(iter(sub.stdout.readline, b"")): 
    print i, line, 
Các vấn đề liên quan