我有一个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?
答案 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()