2017-02-09 72 views
0

如果我使用subprocess.Popen我可以使用communicate()小輸出。替代subprocess.Popen.communicate()流

但是,如果子流程需要花費大量時間併產生大量輸出,我想以流數據的形式訪問它。

有沒有辦法做到這一點? Python的文件說

警告:communicate()而非.stdin.write.stdout.read.stderr.read避免死鎖由於任何其他操作系統管緩衝區填滿並阻塞子進程。

我真的想訪問過程輸出的文件對象:

with someMagicFunction(['path/to/some/command','arg1','arg2','arg3']) as outpipe: 
    # pass outpipe into some other function that takes a file-like object 

,但無法弄清楚如何做到這一點。

回答

1

communicate是一種方便的方法,它啓動後臺線程以讀取stdoutstderr。您可以自己閱讀stdout,但您需要弄清楚如何處理stderr。如果您不關心錯誤,則可以將參數stderr=open(os.devnull, 'wb')或文件stderr=open('somefile', 'wb')添加。或者,創建自己的後臺線程來完成讀取。事實證明shutil已經有這樣的功能,所以我們可以使用它。

import subprocess 
import threading 
import shutil 
import io 

err_buf = io.BytesIO() 

proc = subprocess.Popen(['ls', '-l'], 
    stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
err_thread = threading.Thread(target=shutil.copyfileobj, 
    args=(proc.stderr, err_buf)) 
err_thread.start() 
for line in proc.stdout: 
    print(line.decode('utf-8'), end='') 
retval = proc.wait() 
err_thread.join() 
print('error:', err_buf.getvalue()) 
+0

哦,這很聰明 - 謝謝! –