python - 使用 python subprocess.check_output 进行实时管道或解决方法?

标签 python subprocess pipe

我的一个大型项目的一部分包括一个Python部分,如下所示:

failcount = 0
done = False
while done == False:
    try:
        result = subprocess.check_output(program)
        done = True
    except subprocess.CalledProcessError as e:
        failcount += 1
        logwrite('logfile.txt', 'Failed. Counter = {0}\nError message: {1}\n-'.format(failcount, e.returncode))
        if failcount == 20:
            print 'It failed 20 times, aborting...'
            quit()

这意味着从命令行运行“程序”。 “程序”是一个大型计算化学包,有时会失败,所以我在这里循环运行它。如果失败 20 次,那么我的 python 脚本就会终止。这工作得很好并且达到了预期目的。然而,我的问题是我的化学包每次尝试大约需要三个小时,我想监控它的进展。

如果我从命令行手动运行它,我可以简单地执行“program > logfile”,然后 tail -f 日志文件来观察它的运行情况。然而,你似乎不能在 python 中做类似的事情:

subprocess.check_output(['program', '>', 'logfile'])

有没有办法让 python 在 subprocess.check_output 被填充时打印出它的内容?我认为 subprocess.check_output 仅包含标准输出中的内容。我可以以某种方式在 python 和管道之间克隆它吗?

可能的解决方法:我制作了一个名为 run_program.sh 的 bash 脚本,它只执行上面列出的程序 > 日志文件,然后我使用 python 的子进程来执行 run_program.sh。这样我就可以根据需要进行监控,但现在程序的输出在一个文件中,而不是在 python 中,所以我必须让 python 读取一个大的日志文件,并在需要时捕获错误消息,所以我更愿意如果可以避免这样的事情。

最佳答案

您可以使用 subprocess.Popen 而不是使用 subprocess.check_output 。该对象代表您的子进程,并具有您可以读取的 stdout 和 stderr 属性。如果您的子进程仅使用 stdout,您可能只需在循环中调用 Popen.stdout.readline() 即可。但是,如果子进程写入其他管道,则可能会遇到死锁(有关详细信息,请参阅文档)。在这种情况下,我建议使用 http://stefaanlippens.net/python-asynchronous-subprocess-pipe-reading/ 中描述的 consume 函数。 ,它可以安全地让您逐行打印 stdout 和 stderr,因为它是从子进程输出的。

或者,如果您将 shell=True 传递给check_output 函数。 > 是一个 shell 指令,如果您将其作为独立命令运行,则无法识别该指令。

编辑:上面的内容不会返回任何输出供您的 Python 程序使用。相反,subprocess.check_output('program | tee logfile', shell=True)

如果使用 shell=True,请注意您可以完全控制 check_output 的参数。为了安全起见,切勿允许任何用户或网络输入传递到 shell。请参阅this warning为什么。

关于python - 使用 python subprocess.check_output 进行实时管道或解决方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48814481/

相关文章:

python - 在 Python 循环中构建字典 - 列表和字典理解

python - 将 Python Cement 与 asyncio 相结合

python - 在 pycharm (Windows) 中找不到模块

linux - python subprocess.run 如果你重新定向 stdout/stderr,它会错误退出而不是工作

javascript - ID 名称中带有管道符号 "|"的 jQuery 错误

python - 有没有办法访问用装饰器定义的Python函数的 namespace ?

python - 使用程序接受的用户输入获取程序的输出

python - 子流程中的变量

linux - Perl:关闭信号处理程序中的子进程管道挂起?

java - 为什么我的 Java 代码无法正确执行 bash 命令?