我正在尝试理解subprocess.Popen和subprocess.PIPE。在这样做的同时,我创建了三个小脚本。
本练习的目标是,使用一个脚本打印数据,从另一个脚本中读取数据并将其回显给第一个脚本。
问题是,最后一个sys.stdin.read()阻止整个代码正常工作。
test.py
#!/usr/bin/python3
from subprocess import Popen, PIPE
proc1 = Popen(["python3","script1.py"], stdin=PIPE, stdout=PIPE)
proc2 = Popen(["python3","script2.py"], stdin=PIPE, stdout=PIPE)
first_output = proc1.stdout.read()
print("[test.py:] " + str(first_output))
proc2.stdin.write(first_output)
proc2.stdin.flush()
proc2.stdin.close()
answer = proc2.stdout.read()
print("[test.py:] " + str(answer))
proc1.stdin.write(answer)
script1.py
import sys
sys.stdout.write("Hello world")
sys.stdout.flush()
answer = str(sys.stdin.read())
script1.py answer = str(sys.stdin.read())
中的最后一行会导致整个程序卡住。如果我发表评论,一切正常。
为什么会这样,为什么我无法进一步沟通?我还没有找到答案。
script2.py
import sys
input_read = str(sys.stdin.read())
sys.stdout.write("[script2.py:] " + input_read + " input read")
sys.stdout.flush()
答案 0 :(得分:3)
当你这样做时:
first_output = proc1.stdout.read()
这会尝试阅读proc1
必须说的所有内容;也就是说,它会在文件句柄关闭之前读取。这种情况不会发生,因为proc1
本身正在等待阅读:
answer = str(sys.stdin.read())
使用管道在进程之间进行通信可能有点棘手。我建议您阅读the documentation for the subprocess module。
为解决您的问题,我知道两个简单的解决方案。一种是切换到线路通信。在script1.py
中,写一个换行符:
sys.stdout.write("Hello world\n")
sys.stdouf.flush()
answer = str(sys.stdin.readline())
在script2.py中添加换行符并切换到readline
:
input_read = str(sys.stdin.readline())
sys.stdout.write("[script2.py:] " + input_read + " input read\n")
sys.stdout.flush()
另一种方法是切换到使用read1
而不是阅读。它需要一个参数来读取要读取的字节数,但是在返回之前不会等待接收那么多数据。