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

问题描述 投票:5回答:2

我需要启动一个外部进程,该进程将通过通过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()方法不正确?

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

python subprocess
2个回答
8
投票

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

Popen.communicate(input = None)互动 with process:将数据发送到stdin。读 来自stdout和stderr的数据,直到 到达文件末尾。等待 终止过程。可选的 输入参数应该是一个字符串 被发送到子进程,或无, 如果没有数据应发送到 孩子。

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

更像是:

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()

这将做更多您想要的事情。


0
投票

您可以使用reactor.spawnProcessLineReceiver使用Twisted。

© www.soinside.com 2019 - 2024. All rights reserved.