Общайтесь много раз с процессом, не нарушая трубку?
Это не первый раз, когда я столкнулся с этой проблемой, и это действительно меня беспокоит.
Всякий раз, когда я открываю канал, используя модуль 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
Разрешены ли множественные сообщения?
Ответы
Ответ 1
Я думаю, вы неправильно понимаете, что...
http://docs.python.org/library/subprocess.html#subprocess.Popen.communicate
связывает отправляет строку другому процессу, а затем ждет, пока он закончит... (Как вы сказали, ожидает, что EOF прослушивает stdout и 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)
Ответ 2
У меня была эта проблема раньше, и, насколько я мог когда-либо представить, вы не могли бы сделать этого с помощью subprocess
(что, я согласен, очень противоречиво, если true). Я закончил использование pexpect
(можно получить из PyPI).
Ответ 3
Вы можете использовать:
proc.stdin.write('input')
if proc.stdout.closed:
print(proc.stdout)
Ответ 4
Вы можете сделать это просто с помощью одного вызова 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
, и к этому времени в буфере остается только вторая строка запроса.