2010-06-17 75 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

相關問題