web-dev-qa-db-ja.com

プログラムをバックグラウンドで実行し、その出力をリアルタイムでファイルにリダイレクトします

いくつかのpythonスクリプトを1つのbashセッションで同時に実行し、それぞれの出力をリアルタイムで検査したいと考えています。このタスクを実行するために、以下に示す簡単なbashスクリプトを作成しました。

#!/bin/bash
python 1.py > 1.output &
python 2.py > 2.output &
python 3.py > 3.output &

実行中にcat 1.outputコマンドを使用して何が出力されているかを確認すると、何も表示されません。

しばらく考えてみると、1.outputの実行が終了したら、1.pyに入力する必要があることに気付きました。つまり、ここで使用した方法はreal time形式ではありません。

あなたはこれらのpythonスクリプトの終了を待つことを主張するかもしれません。残念ながら、そこにあるすべてのpythonスクリプトは実際には長期実行プログラムであり、数日または数か月後に終了します。そのため、出力をリアルタイムで検査したいと思います。

また、pythonスクリプトを変更して、メッセージをstdoutの代わりにファイルに直接出力するようにスクリプトを変更することをお勧めします。申し訳ありませんが、ここのスクリプトは変更するには複雑すぎます。それらのprint関数。

私は今何ができますか?

15
Douglas Su

-uスイッチと同等のPYTHONUNBUFFERED環境変数は、stdoutのバッファリングを強制的に解除します。これを試して:

#!/bin/bash
python -u 1.py > 1.output &
python -u 2.py > 2.output &
python -u 3.py > 3.output &

または

#!/bin/bash
export PYTHONUNBUFFERED=yes
python 1.py > 1.output &
python 2.py > 2.output &
python 3.py > 3.output &

ご了承ください -uには副作用があります。詳細については、ドキュメントをご覧ください。

参照:

32
Robᵩ

プログラムにある種のメインループが見つかれば、それは進行状況を示す良い指標となる可能性があるので、ファイルへの書き込みを行うとよいでしょう。出力ストリームがPythonによって閉じられるまで出力が満たされないと言う場合、これがおそらく最も簡単な代替手段です。

0
bcdan

スクリプトでstderr/stdoutをオーバーライドすることを試みることができます:

# in the beginning of your script
import os
import sys

desired_output_file = open('/path/to/file', 'a')
os.dup2(desired_output_file.fileno(), sys.stdout)
os.dup2(desired_output_file.fileno(), sys.stderr)

次に、すべてのprint呼び出しは、標準出力ではなく、この特殊ファイルに書き込みます。ただし、主な問題はバッファIOにある可能性があります。あなたはどういうわけかそのようなファイルのflush内容をディスクに書かなければなりません。

0
Ivan Velichko