2015-12-02 28 views
1

我有從pip包稱爲commandwrapper(其是用於subprocess.popen的包裝:https://pypi.python.org/pypi/commandwrapper/0.7)執行一個終端命令小Python程序。我也試圖捕獲到控制檯和文件的實時輸出。子過程顯示正確在PyCharm但不是sys.stdout來在控制檯

我的代碼:

class Tee(object): 
    def __init__(self, *files): 
     self.files = files 
    def write(self, obj): 
     for f in self.files: 
      f.write(obj) 
      f.flush() 
    def flush(self) : 
     for f in self.files: 
      f.flush() 

# Set the stdout/stderr to Tee() 
out = open(stdout_log, 'w') 
stdout_reset = sys.stdout 
sys.stdout = Tee(sys.stdout, out) 

process = commandwrapper.WrapCommand(command, shell=True) # Also tried False with same behaivor. 
cmd = process.prepareToRun() 

# Stream the output to the console and stdoutfiles 
while cmd.poll() is None: 
    msg_out = cmd.stdout.readline() 
    sys.stdout.write(msg_out) 
    sys.stdout.flush() 

out.close() 

這完美的作品,當我在PyCharm運行它。 command的輸出寫入文件並實時顯示在終端控制檯上。

但是,當我在終端中運行相同的代碼時,控制檯上沒有顯示任何輸出。怎麼會這樣? stdout已正確捕獲到文件中,但沒有任何內容寫入控制檯。

任何人都可以看到任何理由,這個代碼將工作正常,並在PyCharm預期,但不顯示任何標準輸出終端?我在這裏不知所措。如果有的話,如果行爲逆轉,我可以處理它。

使用OSX Yosemite並運行bash

+0

什麼是'commandwrapper.WrapCommand'? –

+0

它是'subprocess.popen'的包裝。我添加了上面的'pip'包的鏈接。感謝您指出了這一點。 – Brett

+0

什麼操作系統和shell? –

回答

1

您需要更改,你有投票的邏輯,我用POPEN,但如果你喜歡,你可以使用包裝:

out = open(stdout_log, 'w') 
stdout_reset = sys.stdout 
sys.stdout = Tee(sys.stdout, out) 
from subprocess import Popen,PIPE,STDOUT 
process = Popen([list_of_cmds],stdout=PIPE,stderr=STDOUT) 
# Stream the output to the console and stdoutfiles 
for line in iter(process.stdout.readline,""): 
    sys.stdout.write(line) 


out.close() 

應用相同的邏輯的工作原理與commandwrapper lib目錄下:

process = commandwrapper.WrapCommand(command, shell=True) # Also tried False with same behaivor. 
cmd = process.prepareToRun() 
# Stream the output to the console and stdoutfiles 
for line in iter(cmd.stdout.readline,""): 
    sys.stdout.write(line) 
+0

這太棒了。謝謝:-) – Brett

+0

沒有問題,不客氣。如果你在while循環外面打印(cmd.stdout.readlines()),你會看到其餘的/所有的輸出,因爲數據正在被緩衝而不管flush –

0

即使子進程已退出,即cmd.poll() is not None,管道中仍可能存在緩衝輸出。如果您在while cmd.poll() is not None循環結束後致電cmd.stdout.read(),您可以看到它。

重現錯誤不Teecommandwrapper

#!/usr/bin/env python 
import sys 
import time 
from subprocess import Popen, PIPE 

#XXX DO NOT USE THE CODE -- ITS PURPOSE IS TO DEMONSTRATE THE ISSUE 
p = Popen([sys.executable, '-c', "import os; os.write(1, b'abc')"], 
      stdout=PIPE, bufsize=0) # no buffering in the parent 
time.sleep(0.3) # allow the child to exit 
while p.poll() is None: # poll() should return non-None value 
    assert 0, "it is never run unless the computer is slow" 
    line = p.stdout.readline() 
    print(line) 

output = p.stdout.read() # 
print("the output left after the child has died: %r" % (output,)) 
assert len(output) >= 3 

參見如何在實時讀取子輸出以及如何將其重定向到某個文件和終端同時這些帖子:

相關問題