実行ファイルを実行しました。bash
./code > log
すべてのprintfステートメントがログファイルに移動している間、端末には時々エラーメッセージが表示されます。以下のようにやり直してください。
./code >& log
これで、時々発生するエラーメッセージも記録されます。ただし、分割エラーがある場合は端末に表示されます。なぜ?メッセージをSegmentation fault (core dumped)
ログファイルに入れるにはどうすればよいですか?
ユーザー $bash --version
GNU bash、バージョン 4.2.24(1)-リリース(i686-pc-linux-gnu)
答え1
「セグメントエラー」メッセージはstderrに印刷されますが、これはプログラムの標準エラーではなく、シェルの標準エラーです。シェルは、プログラムが信号のために終了したことを検出すると、このメッセージを印刷します。
実行中のプログラムのシェルスクリプト部分の周りでstderrをリダイレクトすることで、このメッセージを無音に設定できます。
{ ./code; } >&log
答え2
スプリットエラーはシグナルであり、それをキャプチャできないとプログラムは終了し、シェルはそれを標準エラー(プログラムの標準エラーではない)として印刷します。
これが発生した場合、プログラムまたはシェルはプログラムにシグナルをキャプチャして特定のアクションを実行するか、シェルがSIGCHILDシグナルをキャプチャしてサブプロセスの終了ステータスを確認できます。
答え3
エラーメッセージはリダイレクトされますが、分割エラーがある場合にのみ端末に表示されます。なぜ?
Per GilesのTL / DR:分割エラーメッセージはプログラムで発生しないため、stderr
これらのstdout
メッセージをリダイレクトしても効果はありません。スプリットエラーメッセージは、スプリットエラーサブプロセスを実行するシェルによって生成されます。
後で起こるのは、サブプロセスが終了した後にシェルがwait()
(またはwaitpid()
)を呼び出し、その応答を使用して、サブプロセスが信号の受信によって終了したことを確認することです。
その場合、シェルは通常メッセージを印刷しますが、必ずしもそうではありません。
trap
シェルは魔法のように子供に死ぬという信号を送らないことに注意してください。子供だけが信号を捕捉したり、信号によって死亡したりすることができます。子が死亡すると、親はSIGCHLDを受け取りますが、これは別のシグナルです。
エラーメッセージを印刷または印刷しないことに加えて、シェルは示す終了$?
ステータスも設定します。
$ ./div_by_0
Floating point exception
$ echo $?
136
ゼロ除算などの信号にも同様に適用されます。詳細についてはを参照してくださいman 3 wait
。
これによって発生する1つの結果は、子プロセスがプロセスチェーンの最後のプロセスである場合にのみメッセージを受信することです。
例えば
$ ./div_by_0
Floating point exception
$ echo | ./div_by_0
Floating point exception
$ ./div_by_0 | wc
0 0 0
Gilesによると、コマンド出力をファイルにキャプチャしても、シェルがメッセージを印刷するのを防ぐことはできません。
$ { ./div_by_0 ; } > log
Floating point exception
$ { ./div_by_0 ; } >& log
$ cat log
Floating point exception
ただし、コマンド出力を変数としてキャプチャすると、シェルがメッセージを印刷できなくなります。
$ a=$(./div_by_0)
$ echo $a
$
変数またはファイルの出力をキャプチャしても、出力が設定されるの$?
を妨げません。
$ { ./div_by_0 ; } >& log
$ echo $?
136
$ a=`{ ./div_by_0 ; }`
$ echo $?
136
エラーメッセージで何をしたいかに応じて、上記の内容はすでにあなたのニーズに適している可能性があり、$?
プログラムを呼び出した後に確認したい場合があります。
また、これを使用trap ERR
してエラーをキャッチしてからアクションを呼び出して、$?
SIGSEGV、SIGFPE、または他のものと一致することを確認することもできます。
例えば
$ trap 'exit_code=$?; echo "exit code: $exit_code"; if [[ $exit_code -eq 139 ]]; then echo "segfault"; fi ; if [[ $exit_code -eq 136 ]] ; then echo "div by 0"; fi ;' ERR
$ ./div_by_0
Floating point exception
exit code: 136
div by 0
trap
この機能をオンにすると、設定する前にSIGCHLD
トラップコードが$?
呼び出されるため、目的の結果が出る可能性が低くなります。無効なコマンドは "$?" = 0を返すように見え、次のコマンドはゼロ以外の値を返すように見えます。$?
例えば
$ ./div_by_0
exit code: 0
Floating point exception
$ ./div_by_1
exit code: 136 <-- this is $? from div_by_0, not from div_by_1
div by 0