2017-05-19 68 views
1

在这里有很多事情在少量的代码。我会尽量保持简洁。Python函数捕获子进程标准输出和标准错误日志文件

我有一个python函数,它运行一个外部程序,并将stdout和stderr都指向一个日志文件。

我使用doctest来测试函数。我需要测试输出捕捉功能。下面的代码显示了我编写函数和测试的尝试。测试失败,没有写入日志文件。我不确定问题出在测试或测试代码中,或者两者兼而有之。建议?

from __future__ import print_function 

import subprocess 

def run(command_line, log_file): 
    """ 
    # Verify stdout and stderr are both written to log file in chronological order 
    >>> run("echo text to stdout; echo text to stderr 1>&2", "log") 
    >>> f = open("log"); out = f.read(); f.close() 
    >>> print(out.strip()) 
    text to stdout 
    text to stderr 
    """ 
    command_line = "set -o pipefail; " + command_line + " 2>&1 | tee " + log_file 

    # Run command. Wait for command to complete. If the return code was zero then return, otherwise raise CalledProcessError 
    subprocess.check_call(command_line, shell=True, executable="bash") 

测试结果:

$ python -m doctest testclass.py 
text to stdout 
text to stderr 
********************************************************************** 
File "testclass.py", line 10, in testclass.run 
Failed example: 
    print(out.strip()) 
Expected: 
    text to stdout 
    text to stderr 
Got: 
    <BLANKLINE> 
********************************************************************** 
1 items had failures: 
    1 of 3 in testclass.run 
***Test Failed*** 1 failures. 
+0

你尝试,从产生的bash命令'“set -o pipefail;”+ command_line +“2>&1 | tee” + log_file'在终端?输出是什么样的? –

+0

发送到终端的文本与此命令一样:set -o pipefail;将文本回显到stdout;将文本回显到stderr 1>&2 2>&1 | tee log – Steve

+0

@ Jean-FrançoisFabre这是大批量生产过程中的一小部分,用于生成用户检查处理结果所需的大型日志文件。 – Steve

回答

2

既然做了subprocess.check_callshell=True,2标准输出/标准错误重定向和tee不执行命令和捕捉输出的最佳方式(实际上它是最接近到最糟糕的的方式),我不是真的很惊讶,它失败了。

我的解决方案是删除set -o pipefail初学者(你不需要在这里检查返回代码)并将两个命令都包含在括号中,否则重定向/ tee只适用于最后一个(我仍然困惑你为什么得不到任何输出人所有的,说实话,虽然):

command_line = "(" + command_line + ") 2>&1 | tee " + log_file 

如果你不得不恢复pipefail事情,括号内做到这一点:

command_line = "(set -o pipefail; " + command_line + ") 2>&1 | tee " + log_file 
+0

我认为他根本没有输出,因为他实际上只是将'stderr'文本输送到日志文件,而这可能只是空的。 –

+0

@ThomasKühn,但他正在'echo stderr 1&2'的文本:应该发送文本到stderr。 –

+1

对,我错过了那部分。没有例子,这很难测试。那么现在就解决了;) –

相关问题