問題は、pipe
がいっぱいだということです。サブプロセスは停止し、パイプが空になるのを待ちますが、その後、プロセス (Python インタープリター) が終了し、パイプの終わりが壊れます (したがって、エラー メッセージが表示されます)。
p.wait()
あなたを助けません:
警告子プロセスが stdout または stderr パイプに十分な出力を生成し、OS パイプ バッファーがさらにデータを受け入れるのを待ってブロックする場合、これはデッドロックになります。communicate()
それを回避するために使用します。
http://docs.python.org/library/subprocess.html#subprocess.Popen.wait
p.communicate()
あなたを助けません:
注読み取ったデータはメモリにバッファリングされるため、データ サイズが大きい場合や無制限の場合は、このメソッドを使用しないでください。
http://docs.python.org/library/subprocess.html#subprocess.Popen.communicate
p.stdout.read(num_bytes)
あなたを助けません:
警告communicate()
またはではなく.stdin.write
、.stdout.read
またはを使用.stderr.read
して、他の OS パイプ バッファがいっぱいになり、子プロセスをブロックすることによるデッドロックを回避します。
http://docs.python.org/library/subprocess.html#subprocess.Popen.stdout
この話の教訓は、大規模な出力のsubprocess.PIPE
場合、プログラムがデータを読み取ろうとすると、特定の失敗につながるということです (ループに入れることができるはずですp.stdout.read(bytes)
がwhile p.returncode is None:
、上記の警告は、これが可能性があることを示唆しています)。デッドロック)。
ドキュメントは、シェルパイプをこれに置き換えることを提案しています:
p1 = Popen(["zgrep", "thingiwant", "largefile"], stdout=PIPE)
p2 = Popen(["processreceivingdata"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]
p2
が標準入力を から直接取得していることに注意してくださいp1
。これはデッドロックを回避するはずですが、上記の矛盾した警告を考えると、 .
とにかく、その最後の部分がうまくいかない場合 (ただし、そうあるべきです)、一時ファイルを作成し、最初の呼び出しからすべてのデータを書き込み、一時ファイルを次のプロセスへの入力として使用することができます。