等待未终止的子进程的输出

时间:2013-12-10 04:17:19

标签: python subprocess

我需要从我的脚本运行一个子进程。子进程是一个交互式(类似shell)的应用程序,我通过子进程“stdin向其发出命令。” 发出命令后,子进程将结果输出到stdout,然后等待下一个命令(但不终止)。

例如:

from subprocess import Popen, PIPE
p = Popen(args = [...], stdin = PIPE, stdout = PIPE, stderr = PIPE, shell = False)
# Issue a command:
p.stdin.write('command\n')
# *** HERE: get the result from p.stdout ***
# CONTINUE with the rest of the script once there is not more data in p.stdout
# NOTE that the subprocess is still running and waiting for the next command
# through stdin.

我的问题是从p.stdout获得结果。当p.stdout中有新数据时,脚本需要获取输出;但是一旦没有更多数据,我想继续使用该脚本 子进程没有终止,所以我不能使用communicate()(等待进程终止) 我发出命令之后尝试从p.stdout读取,如下所示:

res = p.stdout.read()

但是子进程不够快,我得到空结果 我想在循环中轮询p.stdout直到我得到一些东西,但那我怎么知道我得到了一切?而且无论如何它似乎都很浪费。

有什么建议吗?

3 个答案:

答案 0 :(得分:0)

在gevent-1.0中使用gevent.subprocess替换标准subprocess模块。它可以使用同步逻辑执行并发任务,并且不会阻止脚本。以下是有关gevent.subprocess

的简要教程

答案 1 :(得分:0)

使用circuits-dev中的circuits.io.Process来包装对子进程的异步调用。

示例:https://bitbucket.org/circuits/circuits-dev/src/tip/examples/ping.py

答案 2 :(得分:0)

在调查了几个选项后,我找到了两个解决方案:

  1. 使用fcntl模块将子进程'stdout流设置为非阻塞。
  2. 使用线程将子进程的输出收集到代理队列,然后从主线程中读取队列。
  3. 我在this post中描述了两个解决方案(以及问题及其来源)。