web-dev-qa-db-ja.com

パイプを壊すことなく、プロセスと複数回通信しますか?

私がこの問題を抱えているのはこれが初めてではなく、それは本当に私を悩ませています。 Python subprocessモジュールを使用してパイプを開くときはいつでも、ドキュメントで指定されているように、communicateは1回しか使用できません。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]

ここでの問題は、2回目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

複数の通信は許可されていますか?

27
Manux

私はあなたがコミュニケーションを誤解していると思います...

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を使用します)

22
Terence Honles

私は以前にこの問題を抱えていましたが、私が理解できる限り、subprocessではこれを行うことができませんでした(これは、本当の場合は非常に直感に反します)。最終的にpexpect(PyPIから入手可能)を使用しました。

4
gilesc

次を使用できます。

proc.stdin.write('input')    
if proc.stdout.closed:
    print(proc.stdout)
2
Daniel

これは、communicate()を1回呼び出すだけで実行できます。

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に1回だけ書き込むことであり、\nはEOLとして機能します。 psqlサブプロセスはstdinから\nまで読み取り、最初のクエリが終了した後、再びstdinに移動します。その時点で、2番目のクエリ文字列のみがバッファに残ります。 。

1
zimplex