It's not the first time I'm having this problem, and it's really bugging me. Whenever I open a pipe using the Python subprocess
module, I can only communicate
with it once, as the documentation specifies: Read data from stdout and stderr, until end-of-file is reached
这不是我第一次遇到这个问题,这真的让我烦恼。每当我使用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]
The problem here is that the second time, Python isn't happy. Indeed, he decided to close the file after the first communicate:
这里的问题是,第二次,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
Are multiple communications allowed?
是否允许多次通信?
4 个解决方案
#1
19
I think you misunderstand communicate...
我觉得你误会了沟通......
http://docs.python.org/library/subprocess.html#subprocess.Popen.communicate
communicate sends a string to the other process and then waits on it to finish... (Like you said waits for the EOF listening to the stdout & stderror)
communication将字符串发送到另一个进程,然后等待它完成...(就像你说等待EOF听stdout和stderror)
What you should do instead is:
你应该做的是:
proc.stdin.write('message')
# ...figure out how long or why you need to wait...
proc.stdin.write('message2')
(and if you need to get the stdout or stderr you'd use proc.stdout or proc.stderr)
(如果你需要获取stdout或stderr,你可以使用proc.stdout或proc.stderr)
#2
4
I've had this problem before, and as far as I could ever figure, you couldn't do this with subprocess
(which, I agree, is very counterintuitive if true). I ended up using pexpect
(obtainable from PyPI).
我以前遇到过这个问题,而且据我所知,你不能用子进程做这个(我同意,如果是真的话,这是违反直觉的)。我最终使用了pexpect(可从PyPI获得)。
#3
2
You can use:
您可以使用:
proc.stdin.write('input')
if proc.stdout.closed:
print(proc.stdout)
#4
1
You can do this simply with single call of communicate()
:
您可以通过单次调用communication()来完成此操作:
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])
The key-point here is that you only write once to stdin
, and \n
serve as EOL. your psql subprocess reads from stdin
until \n
, then after it finishes the first query, it goes to stdin
again, by which time only the second query string is left in the buffer.
这里的关键点是你只对stdin写一次,然后\ n作为EOL。你的psql子进程从stdin读取直到\ n,然后在完成第一个查询之后,再次进入stdin,此时只有第二个查询字符串留在缓冲区中。
#1
19
I think you misunderstand communicate...
我觉得你误会了沟通......
http://docs.python.org/library/subprocess.html#subprocess.Popen.communicate
communicate sends a string to the other process and then waits on it to finish... (Like you said waits for the EOF listening to the stdout & stderror)
communication将字符串发送到另一个进程,然后等待它完成...(就像你说等待EOF听stdout和stderror)
What you should do instead is:
你应该做的是:
proc.stdin.write('message')
# ...figure out how long or why you need to wait...
proc.stdin.write('message2')
(and if you need to get the stdout or stderr you'd use proc.stdout or proc.stderr)
(如果你需要获取stdout或stderr,你可以使用proc.stdout或proc.stderr)
#2
4
I've had this problem before, and as far as I could ever figure, you couldn't do this with subprocess
(which, I agree, is very counterintuitive if true). I ended up using pexpect
(obtainable from PyPI).
我以前遇到过这个问题,而且据我所知,你不能用子进程做这个(我同意,如果是真的话,这是违反直觉的)。我最终使用了pexpect(可从PyPI获得)。
#3
2
You can use:
您可以使用:
proc.stdin.write('input')
if proc.stdout.closed:
print(proc.stdout)
#4
1
You can do this simply with single call of communicate()
:
您可以通过单次调用communication()来完成此操作:
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])
The key-point here is that you only write once to stdin
, and \n
serve as EOL. your psql subprocess reads from stdin
until \n
, then after it finishes the first query, it goes to stdin
again, by which time only the second query string is left in the buffer.
这里的关键点是你只对stdin写一次,然后\ n作为EOL。你的psql子进程从stdin读取直到\ n,然后在完成第一个查询之后,再次进入stdin,此时只有第二个查询字符串留在缓冲区中。