开发者社区 问答 正文

有没有一种方法可以从Python 3的subprocess.run流传输并捕获输出?

如果你这样做

subprocess.run(["echo hi && sleep 60"], shell=True, capture_output=False, timeout=5)

您会在终端上看到“ hi”字样,然后由于超时而引发异常。

但是如果你这样做

ret = subprocess.run(["echo hi && sleep 6"], capture_output=True, timeout=2, shell=True)

您将看不到任何输出,并且(据我所知)超时异常将阻止您获取生成的输出。(对于这个例子,shell = True并不重要,我只是需要一种方便的方法来使其超时。)

这导致了以下问题:我(a)需要获取命令的输出,但是(b)有时会无意中运行挂起的命令,等待用户输入。我真的很想能够捕获产生的任何输出,尽管抛出了Timeout Exception 或将输出流传输到stdout / stderr,同时还获得了它的副本。

问题来源:stackoverflow

展开
收起
is大龙 2020-03-24 19:08:35 703 分享 版权
1 条回答
写回答
取消 提交回答
  • TimeoutExpired异常本身包括任何捕获的输出作为属性(stdoutstderr),因此:

    try:
        ret = subprocess.run("commands go here && sleep 6", capture_output=True, timeout=2, shell=True)
    except subprocess.TimeoutExpired as e:
        print(e.stdout)
    else:
        print(ret.stdout)
    

    当相关命令在超时之前实际写入管道时,它将起作用。

    但是,如果子进程在完成之前被杀死,而子进程仍然在用户模式缓冲区中保留数据(它是块缓冲或行缓冲,并且从来没有写任何换行符之类的东西),那么它永远不会被写入实际的管道中,所以您不会看到它。

    取消子进程的缓冲有很多不同的方式,因此我无法在实际情况下给出具体的操作信息(“ echo”显然只是一个占位符),当子可执行文件时,“ stdbuf”通常非常有用不能修改为行缓冲或无缓冲。

    回答来源:stackoverflow

    2020-03-24 19:08:45
    赞同 展开评论