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

时间:2009-07-06 16:03:58

标签: python subprocess

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

我想要完成的是:

  1. 启动外部流程
  2. 迭代了一些步骤
    1. 通过在其stdin上写一个换行符来告诉外部进程完成下一个处理步骤
    2. 等待外部进程通过在其stdout中写入换行符来表示已完成该步骤
  3. 关闭外部进程的stdin,向外部进程指示执行已完成。
  4. 到目前为止,我已经提出了以下建议:

    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()处阻塞,不再继续。我错误地使用communic()方法?

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

2 个答案:

答案 0 :(得分:8)

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

  

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

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

更像是:

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

这会做更像你想要的事情。

答案 1 :(得分:0)

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