私のPythonコード:
import sys
print "i am a daemon"
print "i will be run using nohup"
sys.stderr.write("i am an error message inside nohup process\n")
コードを実行すると、python a.py
次のように表示されます。
i am a daemon
i will be run using nohup
i am an error message inside nohup process
コードを実行すると、nohup python a.py > a.log 2>&1 < /dev/null &
a.logが表示されます。
i am an error message inside nohup process
i am a daemon
i will be run using nohup
stdoutログを使用するとstderrログがフラッシュ/記録されるのはなぜですかnohup
?
答え1
私はそれが重要ではないと思いますnohup
。これにより同じ動作が発生しますpython a.py > a.log 2>&1
。
Pythonは内部的にCファイルstdioを使用する可能性が高いです。これにより、stdout
端末にいるときにラインバッファリングが発生し、stdout
ファイルのときにバッファリングが発生します。stderr
常にバッファリングされません。
stdout
ファイルにリダイレクトすると、stdout
バッファリングがラインバッファリングからバッファリングに切り替わり、print
ed文字列がバッファに入り、プログラム(ストリーム)が閉じられたときにのみフラッシュされます。ストリームはstderr
バッファリングされないため、ファイルに高速に転送されます。
stdbuf
adjustStandardBufferingを使用して、行を正しい順序で強制的に印刷できます。
stdbuf -o0 python a.py >a.log 2>&1
答え2
これはほとんどの言語で出力ストリームの一般的な動作です。バッファリングつまり、write
メモリ内のバッファが実際に書き込まれ、バッファが一括してストリームに書き込まれます。端末に書き込むときに標準出力はラインバッファリングされますが(つまり、改行文字が印刷されるたびに実際の書き込みが発生します)、通常のファイルまたはパイプに書き込むときに標準出力は完全にバッファリングされます(データはメモリに書き込まれるまで)バッファがいっぱいです。)Stderrはバッファリングされていないか、ラインバッファリングされています。
Pythonでは、ファイルを開くときにバッファリングの種類を選択できますが、標準ストリームは選択できません。すべてのストリームをバッファリング解除するには、以下を設定できます。PYTHONUNBUFFERED
環境変数は、標準ストリームがバッファリングされないように強制します。またはできますstdbuf
または、以下からプログラムを実行してください。unbuffer
。
ただし、標準出力がリダイレクトされたときにプログラムが正しい順序で出力をエクスポートしない場合、これは修正する必要があるプログラムの欠陥です。特に、stdoutに書き込まれた出力に関連するエラーメッセージを発行するには、まずstdoutをフラッシュする必要があります。
print some_data
if errro_condition():
file.stdout.flush()
sys.stderr.write('Bad stuff happened\n')