2012-05-02 39 views
5

Tôi đang gặp một số khó khăn khi nhận được kết quả đầu ra từ một đường ống phụ xử lý. Tôi đang khởi chạy một số mã của bên thứ ba thông qua nó, để trích xuất đầu ra của nhật ký. Cho đến khi cập nhật gần đây mã của bên thứ ba, mọi thứ đều hoạt động tốt. Sau khi cập nhật, python đã bắt đầu chặn vô thời hạn và không thực sự hiển thị bất kỳ đầu ra nào. Tôi có thể khởi chạy ứng dụng của bên thứ ba một cách thủ công và xem kết quả đầu ra.Đầu ra con của Python trên cửa sổ?

Một phiên bản cơ bản của mã Tôi đang sử dụng:

import subprocess, time 
from threading import Thread 

def enqueue_output(out): 
    print "Hello from enqueue_output" 
    for line in iter(out.readline,''): 
     line = line.rstrip("\r\n") 
     print "Got %s" % line 
    out.close() 

proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=1) 
thread = Thread(target=enqueue_output, args=(proc.stdout,)) 
thread.daemon = True 
thread.start() 

time.sleep(30) 

này hoạt động hoàn hảo nếu tôi thay third_party.exe cho kịch bản này:

import time, sys 

while True: 
    print "Test" 
    sys.stdout.flush() 
    time.sleep(1) 

Vì vậy, tôi không rõ ràng như kỳ diệu cần phải được thực hiện để làm việc này với lệnh gốc.

Đây là tất cả các biến thể của dòng subprocess.Popen tôi đã cố gắng nhưng không thành công:

proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=0) 
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, shell=True) 
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, creationflags=subprocess.CREATE_NEW_CONSOLE) 
si = subprocess.STARTUPINFO() 
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW 
proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, startupinfo=si) 

Sửa 1: tôi không thể thực sự sử dụng .communicate() trong trường hợp này. Ứng dụng tôi đang khởi chạy vẫn chạy trong một thời gian dài (vài ngày đến vài tuần). Cách duy nhất tôi thực sự có thể kiểm tra .communicate() sẽ là để giết các ứng dụng ngay sau khi nó ra mắt, mà tôi không cảm thấy sẽ cho tôi kết quả hợp lệ.

Ngay cả những phiên bản không-ren của điều này không:

import subprocess, time 
from threading import Thread 

proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

print "App started, reading output..." 
for line in iter(proc.stdout.readline,''): 
    line = line.rstrip("\r\n") 
    print "Got: %s" % line 

Chỉnh sửa 2: Nhờ JDI, các công việc sau okay:

import tempfile, time, subprocess 

w = "test.txt" 
f = open("test.txt","a") 
p = subprocess.Popen("third_party.exe", shell=True, stdout=f, 
         stderr=subprocess.STDOUT, bufsize=0) 

time.sleep(30) 

with open("test.txt", 'r') as r: 
    for line in r: 
     print line 
f.close() 
+0

Có thể chương trình bên thứ ba của bạn đã chuyển sang viết thành stderr không? – jdi

+0

Dường như không phải như vậy. Nếu tôi chặn stderr thay vào đó, điều tương tự xảy ra (mặc dù, tôi thấy đầu ra của ứng dụng trên giao diện điều khiển, nhưng nó chỉ là in ấn, nó không đi qua Python). – devicenull

+0

Có vẻ như ứng dụng đã ngừng sử dụng đầu ra tiêu chuẩn và đang ghi trực tiếp vào bảng điều khiển. Nếu vậy, bạn không thể làm được gì nhiều về điều này. Bạn có thể kiểm tra với nhà cung cấp ứng dụng không? –

Trả lời

5

Trước tiên tôi xin khuyên bạn nên đơn giản hóa ví dụ này để đảm bảo bạn thực sự có thể đọc bất cứ điều gì. Xóa biến chứng của chuỗi khỏi hỗn hợp:

proc = subprocess.Popen("third_party.exe", stdout=subprocess.PIPE, bufsize=1) 
print proc.communicate() 

Nếu điều đó hiệu quả, tuyệt vời. Sau đó, bạn đang có vấn đề có thể với cách bạn đang đọc stdout trực tiếp hoặc có thể trong chủ đề của bạn.

Nếu điều này không hoạt động, bạn đã thử stderr đường ống để stdout là tốt?

proc = subprocess.Popen("third_party.exe", 
         stdout=subprocess.PIPE, 
         stderr=subprocess.STDOUT, bufsize=1) 

Cập nhật

Vì bạn nói communicate() được deadlocking, đây là cách tiếp cận khác, bạn có thể thử để xem nếu nó là một vấn đề với bộ đệm nội bộ của tiến trình con ...

import tempfile 
import subprocess 

w = tempfile.NamedTemporaryFile() 
p = subprocess.Popen('third_party.exe', shell=True, stdout=w, 
         stderr=subprocess.STDOUT, bufsize=0) 

with open(w.name, 'r') as r: 
    for line in r: 
     print line 
w.close() 
+0

Nếu tôi gặp lỗi với chuỗi, tại sao nó lại hoạt động cho ứng dụng thử nghiệm đơn giản của tôi, nhưng không phải là thực tế? Tôi không thể sử dụng giao tiếp, vì ứng dụng không thực sự kết thúc. Đó là một máy chủ và vẫn chạy trong một thời gian dài. – devicenull

+0

@devicenull: Tôi sẽ nói sự khác biệt là tập lệnh thử nghiệm của bạn đang in 4 ký tự, từ từ, mỗi giây, trong khi tôi không biết loại ứng dụng bên thứ ba của bạn đang làm gì. Bạn có thể bế tắc từ bộ đệm. Ngoài ra, khi bạn có vấn đề như thế này, tốt nhất là nên loại bỏ càng nhiều biến càng tốt và đảm bảo mỗi bước hoạt động chính xác. – jdi

+0

Xuất ra một tệp hoạt động hoàn hảo. Bất kỳ ý tưởng nào tại sao nó hoạt động, nhưng đường ống thì không? – devicenull

2
args = ['svn','log','-v'] 

def foo(info=''): 
    import logging 
    import subprocess 
    import tempfile 
    try: 
     pipe = subprocess.Popen(args,bufsize = 0,\ 
      stdout = subprocess.PIPE,\ 
      stderr=subprocess.STDOUT) 
    except Exception as e: 
     logging.error(str(e)) 
     return False 
    while 1: 
     s = pipe.stdout.read() 
     if s: 
      print s, 
     if pipe.returncode is None: 
      pipe.poll() 
     else: 
      break 
    if not 0 == pipe.returncode: 
     return False 
    return True 

print foo() 

Cái này sẽ hoạt động, không phải là chuỗi, tập tin tạm thời.

Các vấn đề liên quan