2016-10-04 63 views
2

我想重定向標準輸出到屏幕,同時保存到一個變量並運行到錯誤AttributeError: __exit__在線with proc.stdout:,誰能告訴我如何完成這個?如何將stdout重定向到屏幕,並同時保存到變量

............... 
proc = subprocess.Popen(cmd.split(' '), stderr=subprocess.PIPE) 
try: 
    proc.wait(timeout=time_out) 
except TimeoutExpired as e: 
    print e 
    proc.kill() 
with proc.stdout: 
    for line in proc.stdout: 
     print line 

錯誤: -

with proc.stdout: 
AttributeError: __exit__ 

更新: -

proc = subprocess.Popen(cmd.split(' '),stdout=subprocess.PIPE) 
print "Executing %s"%cmd 
try: 
    proc.wait(timeout=time_out)//HUNG here until timeout kicks-in 
except TimeoutExpired as e: 
    print e 
    proc.kill() 
with proc.stdout as stdout: 
    for line in stdout: 
     print line, 
+0

在Linux上,您可以使用'tee'命令 - 即。 'ls | tee output.txt' – furas

+0

我需要這個在窗口 –

回答

0

在創建對象POPEN你有標準錯誤集。當您打開stdout子進程時,無法打開它,因爲您設置了stderr。您可以通過將stdout=subprocess.PIPE添加到Popen對象參數或通過執行with proc.stderr而不是with proc.stderr來解決此問題。此外,你想稍微改變你的聲明,就像這樣。

with proc.stdout as stdout: 
    for line in stdout: 
     sys.stdout.write(line) 
+0

如果我添加'stdout = subprocess.PIPE'我似乎無法將cmd運行時將stdout重定向到屏幕 –

+0

嘗試刪除'stderr = subprocess'.PIPE參數。 –

+0

沒有幫助 –

0

一旦你做出一個stdoutPIPE你可以創建一個循環讀取管道並根據需要將其寫入到儘可能多的地方。與stderr處理使情況有點棘手,因爲你也需要一個背景閱讀器。因此,創建一個線程和一個寫入多個文件的實用程序,您就完成了。

import sys 
import threading 
from StringIO import StringIO 
import subprocess as subp 
import shlex 

def _file_copy_many(fp, *write_to): 
    """Copy from one file object to one or more file objects""" 
    while True: 
     buf = fp.read(65536) 
     if not buf: 
      return 
     for fp in write_to: 
      fp.write(buf) 

# for test 
cmd = "ls -l" 

# will hold stdout and stderr 
outbuf = StringIO() 
errbuf = StringIO() 

# run the command and close its stdin 
proc = subp.Popen(shlex.split(cmd), stdin=subp.PIPE, stdout=subp.PIPE, 
    stderr=subp.PIPE) 
proc.stdin.close() 

# background thread to write stderr to buffer 
stderr_thread = threading.Thread(target=_file_copy_many, 
    args=(proc.stderr, errbuf)) 
stderr_thread.start() 

# write stdout to screen and buffer then wait for program completion 
_file_copy_many(proc.stdout, sys.stdout, outbuf) 
return_code = proc.wait() 

# wait for err thread 
stderr_thread.join() 

# use buffers 
print outbuf.tell(), errbuf.tell() 
outbuf.seek(0) 
errbuf.seek(0) 

這類似於subprocess.Popen.communicate做,但寫入更多的目的地。

相關問題