Подтвердить что ты не робот

Общайтесь много раз с процессом, не нарушая трубку?

Это не первый раз, когда я столкнулся с этой проблемой, и это действительно меня беспокоит. Всякий раз, когда я открываю канал, используя модуль 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

Разрешены ли множественные сообщения?

4b9b3361

Ответ 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, и к этому времени в буфере остается только вторая строка запроса.