Pythonでラッパーを作成しているコマンドラインツール(実際にはいくつか)があります。
このツールは通常、次のように使用されます。
$ path_to_tool -option1 -option2 > file_out
ユーザーは、file_outに書き込まれた出力を取得し、実行中のツールのさまざまなステータスメッセージを表示することもできます。
Stderr(ステータスメッセージ)をファイルに記録しながら、この動作を再現したいと思います。
私が持っているのはこれです:
from subprocess import call
call(['path_to_tool','-option1','option2'], stdout = file_out, stderr = log_file)
これは、stderrが画面に書き込まれないことを除いて、正常に機能します。もちろん、log_fileの内容を画面に出力するコードを追加することもできますが、ユーザーはそれが起こっている間ではなく、すべてが完了した後にそれを見ることができます。
要約すると、望ましい動作は次のとおりです。
私は本当にシンプルなものを見逃している、または思ったよりもはるかに複雑な感じがします...助けてくれてありがとう!
編集:これはLinuxでのみ動作する必要があります。
Python 3。
def tee_pipe(pipe, f1, f2):
for line in pipe:
f1.write(line)
f2.write(line)
proc = subprocess.Popen(["/bin/echo", "hello"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# Open the output files for stdout/err in unbuffered mode.
out_file = open("stderr.log", "wb", 0)
err_file = open("stdout.log", "wb", 0)
stdout = sys.stdout
stderr = sys.stderr
# On Python3 these are wrapped with BufferedTextIO objects that we don't
# want.
if sys.version_info[0] >= 3:
stdout = stdout.buffer
stderr = stderr.buffer
# Start threads to duplicate the pipes.
out_thread = threading.Thread(target=tee_pipe,
args=(proc.stdout, out_file, stdout))
err_thread = threading.Thread(target=tee_pipe,
args=(proc.stderr, err_file, stderr))
out_thread.start()
err_thread.start()
# Wait for the command to finish.
proc.wait()
# Join the pipe threads.
out_thread.join()
err_thread.join()
あなたが探しているのは次のようなものだと思います:
import sys, subprocess
p = subprocess.Popen(cmdline,
stdout=sys.stdout,
stderr=sys.stderr)
出力/ログをファイルに書き込むには、cmdline
を変更して通常のリダイレクトを含めるようにします。これは通常のlinux bash/Shellで行われます。たとえば、コマンドラインにtee
を追加します:cmdline += ' | tee -a logfile.txt'
お役に立てば幸いです。