Python子进程不会和我说话

时间:2018-07-22 14:32:20

标签: python subprocess

我有一个python脚本,该脚本运行另一个python脚本作为子进程。原始脚本使用stdin和stdout与子进程进行通信。我无法让子流程回复来自原始流程的消息。

作为一个最小的示例,假设我有一个脚本asker.py,希望从answerer.py那里获取答案。询问者向发信人的标准输入发送一条消息,而应答者必须发回一条消息,由询问者将其打印出来。

asker.py看起来像这样:

import sys
import subprocess as sub

answerer = sub.Popen(["python", "answerer.py"], stdin=sub.PIPE, stdout=sub.PIPE)
answerer.stdin.write("Are you listening?\n")
answerer.stdin.flush()
reply = answerer.stdout.readline()
print reply

answerer.py看起来像这样:

while (True):
   line = raw_input()
   print "Yes!"

我看不到asker.py可以打印任何内容。相反,它只是挂在readline()调用上。如果我直接从命令行运行answerer.py,它会回答我键入的内容,所以如何使它回复asker?

2 个答案:

答案 0 :(得分:2)

刷新stdout而非stdin

answerer.stdout.flush()  # line 6

或者在没有while True:的情况下进行测试,以便answerer.py被终止并且Yes!被自动刷新。

经过测试

Python 2.7.13 (default, Apr  4 2017, 08:47:57) 
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)] on darwin

答案 1 :(得分:0)

该子进程实际上没有将任何内容写入其自己的stdout,因此没有任何内容到达父级。

documentation for sys.stdout笔记

  

交互式时,stdout和stderr流是行缓冲的。否则,它们将像常规文本文件一样被块缓冲。

这意味着,当您print "Yes!"进入内存中的缓冲区并坐在那里直到显式刷新为止,会产生一定数量的输出数据(我认为通常为4 KB)或程序正常退出。

最好的解决办法是将您的子流程脚本更新为类似的

#!/usr/bin/env python3
import sys
while True:
  line = input()
  sys.stdout.write("Yes!\n")
  sys.stdout.flush()