バッファリングされていないサブプロセス出力 (最後の行が欠落しています)
-
19-09-2019 - |
質問
私はひどく明白なことを見落としているに違いありません。C プログラムを実行し、その出力をリアルタイムで表示し、最後に最後の行を解析する必要があります。これは、出力された最後の行が次のようになっているため、簡単なはずです。 いつも 同じ。
process = subprocess.Popen(args, shell = True,
stdout = subprocess.PIPE, stderr = subprocess.PIPE)
# None indicates that the process hasn't terminated yet.
while process.poll() is None:
# Always save the last non-emtpy line that was output by the child
# process, as it will write an empty line when closing its stdout.
out = process.stdout.readline()
if out:
last_non_empty_line = out
if verbose:
sys.stdout.write(out)
sys.stdout.flush()
# Parse 'out' here...
ただし、場合によっては、最後の行が印刷されないことがあります。Popens のデフォルト値 バフサイズ は 0 なので、バッファリングされていないはずです。私も試してみましたが、無駄でした fflush(標準出力) 終了直前に C コードにフラッシュする必要がありますが、プログラムを終了する前にストリームをフラッシュする必要はまったくないようです。
誰かアイデアはありますか?
解決
readline()
テキストをバッファリングして改行を待つ必要があります。
常に競合状態が発生します。行を処理し、終了を確認してから行を読み取るという事実を、バッファリングされていないストリームがいくら処理しても処理できないため、行の処理中にサブプロセスが終了すると、 、他には何も読みません。さらに、シェルはおそらく独自のバッファリングを導入しています。
したがって、次のいずれかを行うことができます。
使用
communicate()
サブプロセスの実行中は詳細な出力を放棄します。プロセスが終了した後も、EOF が発生するまで読み取りを続けてください。
また、を使用する必要がないようにコードを変更することをお勧めします。 shell=True
.
他のヒント
問題があるため、シェルフラグのバッファリングを使用しない間、あなたは(process.poll()
)、プロセスが終了するまでのラインを読んでいるということです。
あなたは、ファイルまたは空行の終わりに達するまでprocess.stdoutを読み続ける必要があります。