14

python subprocess.Popen() 呼び出しを使用して子プロセスと通信しようとしています。私の実際のコードでは、ある種の IPC を実装しているので、データを書き込み、応答を読み取り、さらにデータを書き込み、応答を読み取ります。このため、Popen.communicate() を使用できません。それ以外の場合は、単純なケースでうまく機能します。

このコードは私の問題を示しています。最初の応答すら得られず、最初の「読み取り結果」でハングします。なんで?これを期待どおりに機能させるにはどうすればよいですか?

import subprocess
p = subprocess.Popen(["sed", 's/a/x/g'],
                     stdout = subprocess.PIPE,
                     stdin = subprocess.PIPE)

p.stdin.write("abc\n")
print "Reading result:"
print p.stdout.readline()

p.stdin.write("cat\n")
print "Reading result:"
print p.stdout.readline()
4

2 に答える 2

6

sedの出力はバッファリングされ、十分な量が蓄積されるか、入力ストリームが使い果たされて閉じられるまで、そのデータのみを出力します。

これを試して:

import subprocess
p = subprocess.Popen(["sed", 's/a/x/g'],
                     stdout = subprocess.PIPE,
                     stdin = subprocess.PIPE)

p.stdin.write("abc\n")
p.stdin.write("cat\n")
p.stdin.close()

print "Reading result 1:"
print p.stdout.readline()

print "Reading result 2:"
print p.stdout.readline()

stdinこれは、バッファがいっぱいになると、ブロックに書き込むような巨大なデータを確実に実行できないことに注意してください。を使用するのが最善の方法ですcommunicate()

于 2012-04-28T13:27:22.147 に答える
5

Popen().communicate()可能であれば使用してみPopen()ますが、説明したとおりに使用する必要がある場合は、sed を設定して改行後のバッファを-lオプションでフラッシュする必要があります。

p = subprocess.Popen(['sed', '-l', 's/a/x/g'],
                     stdout=subprocess.PIPE,
                     stdin=subprocess.PIPE)

そしてあなたのコードはうまくいくはずです

于 2012-04-28T15:27:35.397 に答える