Python 在不破坏管道的情况下与流程进行多次通信?

Python 在不破坏管道的情况下与流程进行多次通信?,python,pipe,subprocess,Python,Pipe,Subprocess,这不是我第一次有这个问题了,它真的让我很烦恼。 每当我使用Python子流程模块打开管道时,我只能与它进行一次通信,如文档所述:从stdout和stderr读取数据,直到到达文件末尾 proc = sub.Popen("psql -h darwin -d main_db".split(),stdin=sub.PIPE,stdout=sub.PIPE) print proc.communicate("select a,b,result from experiment_1412;\n")[0] pr

这不是我第一次有这个问题了,它真的让我很烦恼。 每当我使用Python
子流程
模块打开管道时,我只能与它进行一次
通信
,如文档所述:
从stdout和stderr读取数据,直到到达文件末尾

proc = sub.Popen("psql -h darwin -d main_db".split(),stdin=sub.PIPE,stdout=sub.PIPE)
print proc.communicate("select a,b,result from experiment_1412;\n")[0]
print proc.communicate("select theta,zeta,result from experiment_2099\n")[0]
这里的问题是,第二次,Python不高兴。事实上,他决定在第一次沟通后关闭该文件:

Traceback (most recent call last):
File "a.py", line 30, in <module>
    print proc.communicate("select theta,zeta,result from experiment_2099\n")[0]
File "/usr/lib64/python2.5/subprocess.py", line 667, in communicate
    return self._communicate(input)
File "/usr/lib64/python2.5/subprocess.py", line 1124, in _communicate
     self.stdin.flush()
ValueError: I/O operation on closed file
回溯(最近一次呼叫最后一次):
文件“a.py”,第30行,在
打印过程通信(“选择θ、zeta、实验结果_2099\n”)[0]
文件“/usr/lib64/python2.5/subprocess.py”,第667行,在communicate中
返回自我。\u通信(输入)
文件“/usr/lib64/python2.5/subprocess.py”,第1124行,在
self.stdin.flush()
ValueError:对关闭的文件执行I/O操作

允许多个通信吗?

我以前遇到过这个问题,据我所知,您无法使用
子流程来实现这一点(我同意,如果是这样的话,这是非常违反直觉的)。我最终使用了
pexpect
(可从PyPI获得)。

我以前遇到过这个问题,据我所知,您无法使用
子流程
(我同意,如果是这样的话,这是非常违反直觉的)。我最终使用了
pexpect
(可从PyPI获得)。

我想你误解了

Communication向另一个进程发送字符串,然后等待它完成。。。(如您所说,等待EOF收听标准输出和标准输出)

你应该做的是:

proc.stdin.write('message')

# ...figure out how long or why you need to wait...

proc.stdin.write('message2')

(如果您需要获取stdout或stderr,您可以使用proc.stdout或proc.stderr)

我认为您误解了

Communication向另一个进程发送字符串,然后等待它完成。。。(如您所说,等待EOF收听标准输出和标准输出)

你应该做的是:

proc.stdin.write('message')

# ...figure out how long or why you need to wait...

proc.stdin.write('message2')
(如果您需要获取stdout或stderr,您可以使用proc.stdout或proc.stderr)

您可以使用:

proc.stdin.write('input')    
if proc.stdout.closed:
    print(proc.stdout)
您可以使用:

proc.stdin.write('input')    
if proc.stdout.closed:
    print(proc.stdout)

只需一次调用
communicate()
,就可以做到这一点:

这里的关键点是,您只需向
stdin
写入一次,而
\n
作为下线。
psql子进程从
stdin
读取数据,直到
\n
,然后在完成第一个查询后,再次转到
stdin
,此时缓冲区中只剩下第二个查询字符串

只需一次调用
communicate()
,就可以做到这一点:

这里的关键点是,您只需向
stdin
写入一次,而
\n
作为下线。
psql子进程从
stdin
读取数据,直到
\n
,然后在完成第一个查询后,再次转到
stdin
,此时缓冲区中只剩下第二个查询字符串

我意识到您可能想查看@(这是一个非常类似的问题)是的,我确实需要非阻塞读取,因为写入可能始终取决于读取的内容。警告:使用
communicate()
而不是
.stdin.write
.stdout.read
.stderr.read
以避免由于任何其他操作系统管道缓冲区填满并阻塞子进程而导致死锁。我意识到您可能希望查看@(这是一个非常类似的问题)是的,确实,我需要非阻塞读取,因为写入可能始终取决于读取的内容。警告:>警告:使用
communicate()
而不是
.stdin.write
.stdout.read
.stderr.read
避免由于任何其他操作系统管道缓冲区填满并阻塞子进程而导致死锁。对于psql,有许多现有的Python包装器:对于psql,有许多现有的Python包装器:这会缓冲内存中的整个输入,使解决方案在需要流式I/O的情况下不太理想。这会缓冲内存中的整个输入,使解决方案在需要流式I/O的情况下不太理想。