在引发异常时捕获subprocess.Popen的stdout

时间:2019-07-17 09:31:56

标签: python exception subprocess

在出现异常时如何从子进程中捕获stdout / stderr.Popen CMD调用?

代码段:

p_cmd = subprocess.Popen(CMD, bufsize=0, shell=True, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(cmd_stdo, cmd_stde) = p_cmd.communicate(timeout=60)

如果CMD是timeout,且运行在60 secs之上,我如何在cmd_stdocmd_stde中获得CMD标准输出?

我尝试在try, exception块中获取它,它为NULL。 而且,我非常确定运行CMD时会有输出。

2 个答案:

答案 0 :(得分:0)

如果超时,则不会分配变量cmd_stdocmd_stde,因为异常发生在分配之前。

为确保即使在异常情况下也捕获了stdoutstderr,我将捕获到(临时)文件,然后将它们读入变量。

import subprocess
from tempfile import TemporaryFile as Tmp

CMD = [ 'echo "before sleep" ; sleep 7 ; echo "after sleep"' ]

with Tmp() as out, Tmp() as err:
    p_cmd = subprocess.Popen(CMD, bufsize=0, shell=True, stdin=None, stdout=out, stderr=err)
    timed_out = False
    try:
        p_cmd.wait(timeout=5)
    except subprocess.TimeoutExpired:
        timed_out = True
    out.seek(0)
    err.seek(0)
    str_out = out.read()
    str_err = err.read()

print('Has timed out:', timed_out)
print('Stdout:', str_out)
print('Stderr:', str_err)

(尝试此操作时,请在代码中使用睡眠和超时​​时间进行操作,以使超时发生与否)

答案 1 :(得分:0)

由于我没有足够的声誉,所以我必须以这种方式要求澄清。

您是否要在Windows或Linux上运行它?