2010-09-26 184 views
7

我有一個長期運行的Python腳本,我從命令行運行。該腳本將進度消息和結果寫入標準輸出。我想捕獲腳本寫入文件中標準輸出的所有內容,但也可以在命令行中看到它。或者,我希望輸出立即進入文件,因此我可以使用tail查看進度。我試過這個:如何將腳本輸出寫入文件和命令行?

python MyLongRunngingScript.py | tee log.txt 

但它不產生任何輸出(只是運行腳本產生預期的輸出)。任何人都可以提出一個簡單的解我正在使用Mac OS X 10.6.4。

編輯我在我的腳本中使用print輸出。

回答

16

你是在正確的道路上,但問題是python緩衝輸出。

幸運的是有一種方法來告訴它不要緩衝輸出:

python -u MyLongRunngingScript.py | tee log.txt 
+3

不要忘記了''stderr''流重定向到''stdout''如果你也想捕捉: ''python -u MyLongRunngingScript.py 2>&1 | tee log.txt'' – stephenfin 2013-12-11 10:54:44

1

您可以嘗試偶爾在腳本中執行sys.stdout.flush(),並再次使用tee運行。當stdout被重定向到tee時,它可能被緩衝的時間比直接到達終端的時間長。

2

事實上,你什麼都看不到,可能與緩衝發生的事實有關。所以你只能得到每4克文本左右的輸出。

相反,嘗試這樣的事:

class OutputSplitter(object): 
    def __init__(self, real_output, *open_files): 
     self.__stdout = real_output 
     self.__fds = open_files 
     self.encoding = real_output.encoding 
    def write(self, string): 
     self.__stdout.write(string) # don't catch exception on that one. 
     self.__stdout.flush() 
     for fd in self.__fds: 
      try: 
       fd.write(string) 
       fd.flush() 
      except IOError: 
       pass # do what you want here. 
    def flush(self): 
     pass # already flushed 

然後裝飾sys.stdout的與該類一些代碼這樣的:

stdout_saved = sys.stdout 
logfile = open("log.txt","a") # check exception on that one. 
sys.stdout = OutputSplitter(stdout_saved, logfile) 

這樣,每次輸出(包括print)被刷新到標準輸出和指定的文件。可能需要調整,因爲我沒有測試過這個實現。

當然,打印消息時會期望看到(大部分時間很小)的性能損失。

相關問題