25

これはこの質問のフォローアップですが、に引数stdinを渡したい場合、どうすればsubprocessリアルタイムで出力を取得できますか? これは私が現在持っているものです。モジュールからの置き換えも試みましPopenたが、これはスクリプトのハングにつながります。callsubprocess

from subprocess import Popen, PIPE, STDOUT
cmd = 'rsync --rsh=ssh -rv --files-from=- thisdir/ servername:folder/'
p = Popen(cmd.split(), stdout=PIPE, stdin=PIPE, stderr=STDOUT)
subfolders = '\n'.join(['subfolder1','subfolder2'])
output = p.communicate(input=subfolders)[0]
print output

渡す必要がなかった前の質問ではstdin、使用するように提案されましたがp.stdout.readline、そこには何かをパイプする余地がありませんstdin

補遺: これは転送には機能しますが、出力は最後にしか表示されず、転送が行われている間に詳細を確認したいと思います。

4

3 に答える 3

37

サブプロセスから標準出力をリアルタイムで取得するには、必要な動作を正確に決定する必要があります。具体的には、出力を行ごとに処理するか、文字ごとに処理するか、および出力を待機している間はブロックするか、待機中に他のことを実行できるようにするかを決定する必要があります。

あなたのケースでは、行バッファ方式で出力を読み取り、完全な行が入るまでブロックするだけでおそらく十分であるように見えます。これは、によって提供される便利な関数でsubprocess十分であることを意味します。

p = subprocess.Popen(some_cmd, stdout=subprocess.PIPE)
# Grab stdout line by line as it becomes available.  This will loop until 
# p terminates.
while p.poll() is None:
    l = p.stdout.readline() # This blocks until it receives a newline.
    print l
# When the subprocess terminates there might be unconsumed output 
# that still needs to be processed.
print p.stdout.read()

プロセスの標準入力に書き込む必要がある場合は、別のパイプを使用してください。

p = subprocess.Popen(some_cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
# Send input to p.
p.stdin.write("some input\n")
p.stdin.flush()
# Now start grabbing output.
while p.poll() is None:
    l = p.stdout.readline()
    print l
print p.stdout.read()

サブプロセスに入力を渡すためにファイルを介して間接的にする必要はありません。

于 2013-07-01T20:25:42.457 に答える
3

このようなものだと思います

from subprocess import Popen, PIPE, STDOUT

p = Popen('c:/python26/python printingTest.py', stdout = PIPE, 
        stderr = PIPE)
for line in iter(p.stdout.readline, ''):
    print line
p.stdout.close()

イテレータを使用すると、基本的にライブ結果が返されます..

入力を標準入力に送信するには、次のようなものが必要です

other_input = "some extra input stuff"
with open("to_input.txt","w") as f:
   f.write(other_input)
p = Popen('c:/python26/python printingTest.py < some_input_redirection_thing', 
         stdin = open("to_input.txt"),
         stdout = PIPE, 
         stderr = PIPE)

これは、次の Linux シェル コマンドに似ています。

%prompt%> some_file.o < cat to_input.txt

標準入力へのより良い受け渡しについては、アルプスの回答を参照してください

于 2013-07-01T19:21:30.120 に答える