【问题标题】:capture stdout of subprocess.Popen when there is exception raised引发异常时捕获 subprocess.Popen 的标准输出
【发布时间】:2019-11-26 02:28:56
【问题描述】:

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

代码sn-p:

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 时有 OUTPUT。

【问题讨论】:

    标签: python exception subprocess


    【解决方案1】:

    在超时的情况下,变量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)
    

    (尝试此操作时,请在代码中使用睡眠和超时​​时间来确定是否发生超时)

    【讨论】:

    • 感谢您的支持。所以如果它们(错误,出)是文件,它们会逐渐更新吗?如果它们是 vars,它们将在出现异常时分配。
    • 文件是“逐渐更新”的,是的,但依赖于缓冲。使用变量时,即使在 try..except 内部,对变量的实际赋值也不会真正发生。试试看吧。
    【解决方案2】:

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

    您是要在 Windows 还是 Linux 上运行它?

    【讨论】:

      猜你喜欢
      • 2010-12-21
      • 2021-01-29
      • 1970-01-01
      • 2021-05-21
      • 1970-01-01
      • 2022-10-20
      • 2016-05-31
      • 2011-11-30
      • 1970-01-01
      相关资源
      最近更新 更多