Python 读取/写入Popen()子进程

Python 读取/写入Popen()子进程,python,subprocess,popen,python-2.6,Python,Subprocess,Popen,Python 2.6,我试图使用python subprocess.Popen()调用与子进程对话。在我的实际代码中,我正在实现一种IPC,所以我想写一些数据,读取响应,再写一些数据,读取响应,等等。正因为如此,我无法使用Popen.communicate(),否则它在简单情况下工作得很好 这段代码显示了我的问题。它甚至从未得到第一个响应,挂起在第一个“读取结果”上。为什么?我怎样才能使这项工作达到我的预期 import subprocess p = subprocess.Popen(["sed", 's/a/x/g

我试图使用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()

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
会阻塞大量数据。最好的方法是使用。

如果可以的话,我会尝试使用
Popen().communicate()
,因为它为您做了很多好事,但是如果您需要完全按照您描述的那样使用
Popen()
,则需要使用
-l
选项将sed设置为在换行后刷新其缓冲区:

p = subprocess.Popen(['sed', '-l', 's/a/x/g'],
                     stdout=subprocess.PIPE,
                     stdin=subprocess.PIPE)

您的代码应该可以正常工作

,但是sed在shell中直接运行命令时不会这样做。如果您这样做,响应将出现在每一行之后。即使在编写之后调用p.stdin.flush(),问题仍然存在。另外,在现实生活中,我也编写了被调用的程序,它没有缓冲,并且以相同的方式运行。我不相信缓冲是这里的问题。add bufsize=0可以解决您的问题
subprocess.Popen(['sed'、'-l'、's/a/x/g'],bufsize=0,stdin=PIPE,stdout=PIPE)
确实有效!出于某种原因,我的sed使用-u表示“无缓冲”,而不是-l,但它的工作原理是一样的。这解决了我的示例代码,但不幸的是,这不是我真正的代码,因为实际的命令不是sed,而是另一个python程序。回答得很好,你指出了问题所在。是的,问题解决了。问题是结果的输出缓冲。在我的子进程中执行一个简单的stdout.flush()解决了这个问题。谢谢