通过流程多次沟通而不会破坏管道?

时间:2010-06-17 19:43:03

标签: python pipe subprocess

这不是我第一次遇到这个问题,这真的让我烦恼。 每当我使用Python subprocess模块打开管道时,我只能communicate一次,因为文档指定:Read data from stdout and stderr, until end-of-file is reached

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

是否允许多方通讯?

4 个答案:

答案 0 :(得分:22)

我认为你误解了沟通......

http://docs.python.org/library/subprocess.html#subprocess.Popen.communicate

communication将一个字符串发送到另一个进程,然后等待它完成...(就像你说的等待EOF听stdout&amp; stderror)

你应该做的是:

proc.stdin.write('message')

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

proc.stdin.write('message2')

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

答案 1 :(得分:4)

我以前遇到过这个问题,而且就我所知,你不能用subprocess做到这一点(我同意,如果这是真的,那就非常违反直觉)。我最终使用pexpect(可从PyPI获得)。

答案 2 :(得分:2)

您可以使用:

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

答案 3 :(得分:1)

您只需拨打communicate()

即可完成此操作
query1 = 'select a,b,result from experiment_1412;'
query1 = 'select theta,zeta,result from experiment_2099;'
concat_query = "{}\n{}".format(query1, query2)
print(proc.communicate(input=concat_query.encode('utf-8'))[0])

这里的关键点是,您只需向stdin写一次,\n用作EOL。 你的psql子进程从stdin读取到\n,然后在完成第一个查询之后再次进入stdin,到那时只有第二个查询字符串留在缓冲区中。