使用Python通过STDIN / STDOUT启动和控制外部进程


问题内容

我需要启动一个外部进程,该进程可以通过通过stdin和stdout发送和发送的消息来控制。使用subprocess.Popen,我可以启动进程,但无法按需要通过stdin控制执行。

我要完成的流程是:

  1. 开始外部过程
  2. 迭代一些步骤
    1. 通过在标准输入中写入换行符来告诉外部过程完成下一步
    2. 等待外部进程通过在标准输出中写入换行符来表明已完成该步骤
  3. 关闭外部进程的标准输入,以向外部进程指示执行已完成。

到目前为止,我已经提出了以下建议:

process = subprocess.Popen([PathToProcess], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
for i in xrange(StepsToComplete):
    print "Forcing step # %s" % i
    process.communicate(input='\n')

当我运行上面的代码时,’\
n’不会传递给外部进程,并且我永远也不会超越步骤#0。该代码在process.communicate()处阻塞,并且不再继续进行。我使用的communication()方法不正确?

另外,我将如何实现“等到外部进程写入新行”功能?


问题答案:

process.communicate(input =’\
n')是错误的。如果您从Python文档中注意到,它会将您的字符串写入子级的stdin,然后读取子级的所有输出,直到子级退出。来自doc.python.org

Popen.communicate(input =
None)与进程交互:将数据发送到stdin。从stdout和stderr读取数据,直到到达文件末尾。等待进程终止。可选输入参数应该是要发送给子进程的字符串,如果没有数据要发送给子进程,则为None。

相反,您只想写孩子的标准输入。然后在循环中读取它。

更像是:

process=subprocess.Popen([PathToProcess],stdin=subprocess.PIPE,stdout=subprocess.PIPE);
for i in xrange(StepsToComplete):
    print "Forcing step # %s"%i
    process.stdin.write("\n")
    result=process.stdout.readline()

这会做得更像您想要的。