Python subprocess.check_call - 如何将stdout和stderr指向_both_屏幕和日志文件?

时间:2012-06-27 21:40:03

标签: python subprocess

我使用的是Python 2.7。这就是我目前正在做的从Python启动其他程序,将STDOUT和STERR重定向到LOGFILE:

    try:
    # Execute command and print content to LOGFILE
        tempname = os.path.abspath('./text.txt')
        TEMPFILE = open(tempname, 'wb')
        print 'Executing: ', command
        subprocess.check_call(command, shell = True, stdout = TEMPFILE, stderr = TEMPFILE)
        TEMPFILE.close()
        LOGFILE.write(open(tempname, 'rU').read())
        LOGFILE.close()
        os.remove(tempname)
    except Exception as errmsg:
    # If fails then print errors to LOGFILE
        TEMPFILE.close()
        LOGFILE.write(open(tempname, 'rU').read())
        os.remove(tempname)
        print messages.crit_error_bad_command % command, '\n', str(errmsg)
        print >> LOGFILE, messages.crit_error_bad_command % command, '\n', str(errmsg)
        LOGFILE.close() 

首先,我不确定我的上述脚本是否是最佳解决方案。我不得不使用临时文件,因为即使在subprocess.check_call调用失败的情况下我也想捕获日志。如果您有如何改进上述脚本的想法,我会很感激。

此外,我想更改此设置,以便STDOUT和STDERR应该正常进入屏幕,也可以进入日志文件。我该怎么做呢?请注意,如果我没有指定STDOUT,我会看到“有错误,你想继续[y / n]吗?”在屏幕上然后我可以对它作出反应。现在,因为一切都进入日志,我在屏幕上看不到任何内容。这里我的问题的答案应该有助于解决这个问题。

感谢。

1 个答案:

答案 0 :(得分:1)

  

我会看到“有错误,你想继续[y / n]吗?”在屏幕上然后我可以对它作出反应。

要重定向子流程'stdout并手动或使用预定义的答案与流程交互,您可以使用pexpect

from contextlib import closing
import pexpect

with open('text.txt', 'rb') as logfile:
    with closing(pexpect.spawn(command, logfile=logfile)) as child:
        # call here child.expect(), child.sendline(), child.interact(), etc

使用subprocess.Popen实现相同的功能是not trivial