2010-06-17 68 views
22

这不是我第一次遇到这个问题,它真的让我烦恼。 每当我使用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 

是否允许多个通信?

+0

对于psql,有很多现有的Python包装:http://wiki.python.org/moin/PostgreSQL – 2012-06-13 12:16:13

回答

18

我想你误会沟通...

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

通信将字符串发送到其他进程,然后等待它完成......(像你说的EOF等待听标准输出& stderror)

你应该做的却是:

proc.stdin.write('message') 

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

proc.stdin.write('message2') 

(如果哟u需要获得stdout或stderr你会使用proc.stdout或proc.stderr)

+0

我意识到你可能想看@ http://stackoverflow.com/questions/375427/non-blocking -read-on-stream-in-python(这是一个非常类似的问题) – 2010-06-18 01:53:36

+1

确实,我需要非阻塞式读取,因为写入可能总是取决于读取的内容。 – Manux 2010-06-18 02:37:45

4

我以前有过这个问题,并且据我所知,你不能用subprocess(我同意,如果真的是非常违反直觉)做到这一点。我结束了使用pexpect(可从PyPI获得)。

1

您可以使用:

proc.stdin.write('input')  
if proc.stdout.closed: 
    print(proc.stdout) 
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,届时只有第二个查询字符串保留在缓冲区中。

+0

谢谢,你是对的。更新。 – zimplex 2015-10-21 08:10:18

+0

这会将整个输入缓冲在内存中,使得解决方案对于需要流式I/O的情况而言不太理想。 – weaver 2017-09-30 16:25:51

相关问题