我正在尝试使用python subprocess.Popen()调用与子进程通信。在我的实际代码中,我正在实现一种类型的IPC,因此我想编写一些数据,读取响应,写入更多数据,读取响应等等。因此,我不能使用Popen.communicate(),否则在简单的情况下效果很好。
此代码显示了我的问题。它从来没有得到第一个响应,挂在第一个“阅读结果”。为什么?我怎样才能按照我的预期完成这项工作?
import subprocess
p = subprocess.Popen(["sed", 's/a/x/g'],
stdout = subprocess.PIPE,
stdin = subprocess.PIPE)
p.stdin.write("abc\n")
print "Reading result:"
print p.stdout.readline()
p.stdin.write("cat\n")
print "Reading result:"
print p.stdout.readline()
答案 0 :(得分:4)
sed
的输出被缓冲,只输出其数据,直到累积足够的或输入流耗尽并关闭。
试试这个:
import subprocess
p = subprocess.Popen(["sed", 's/a/x/g'],
stdout = subprocess.PIPE,
stdin = subprocess.PIPE)
p.stdin.write("abc\n")
p.stdin.write("cat\n")
p.stdin.close()
print "Reading result 1:"
print p.stdout.readline()
print "Reading result 2:"
print p.stdout.readline()
请注意,一旦缓冲区满了,就无法可靠地完成哪些大数据作为stdin
的阻塞。最好的方法是使用communicate()
。
答案 1 :(得分:4)
我会尽量使用Popen().communicate()
,因为它可以为你做很多好事,但如果你需要完全按照你的描述使用Popen()
,你需要设置sed使用-l
选项在换行符后刷新缓冲区:
p = subprocess.Popen(['sed', '-l', 's/a/x/g'],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
并且您的代码应该可以正常工作