2010-09-26 155 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)被刷新到标准输出和指定的文件。可能需要调整,因为我没有测试过这个实现。

当然,打印消息时会期望看到(大部分时间很小)的性能损失。

相关问题