シェルスクリプト終了コード

シェルスクリプト終了コード

bash 終了コードについて質問があります。基本的に私が返す各コードの意味を定義できますか?それでは、これを定義または文書化する標準的な方法はありますか?

私はそれを調べたところ、「共通」終了コードのさまざまなリストがあることがわかりました。例えば

また、いくつかのGNU文書を見てみると、少し混乱していることがわかりました。

シャットダウン状態は 0 ~ 255 ですが、シェルは以下のように具体的に 125 より高い値を使用できます。

どのような標準的な慣行があるのだろうか。

答え1

上記のコードのほとんどはゴミです。これは正式な定義ではありません。私は別のものを見つけました。高度なバッシュスクリプトガイド

Exit Code Number
1   Catchall for general errors
2   Misuse of shell builtins (according to Bash documentation)
126 Command invoked cannot execute
127 "command not found"
128 Invalid argument to exit
128+n   Fatal error signal "n"
130 Script terminated by Control-C
255*    Exit status out of range

しかし、これらのコードは提案したがって、あなたの目的に合わせて自由に使用してください。

答え2

これは、個々のビットまたはビット範囲が特定の意味を持つstatus16ビットワードです(JSONに似ていますが、1970年代には特にJSONなどの複雑な操作以降は16ビットレジスタが一般的ではありませんでした)。forkPerlは、呼び出しによって設定された16ビットの単語をwait(2)変数に入れ、$?上位ビットを移動して特定の終了コードを見つけることができます。なぜなら、フィールドが単語内の場所であるからです。

$ perl -e 'fork || exit 42; wait; printf "%016b\n", $?'
0010101000000000
$ perl -e 'fork || exit 42; wait; printf "%016b\n", $? >> 8'
0000000000101010
$ perl -e 'fork || exit 42; wait; printf "%d\n", $? >> 8'
42

Unixシェルはstatus16ビットの単語を別の形式に変換します。

$ perl -e 'exit 42'; echo $?
42

これは、コアダンプ(16ビットワードにフラグがある)または信号がある場合に関連します。

$ perl -MPOSIX -e 'raise SIGTERM'; echo $?
Terminated
143
$ echo $((143-128))
15
$ kill -l | grep 15
15   TERM Terminated                    31   USR2 User defined signal 2

したがって、これはシグナル番号に128を加算し(シェルはこの値を変更します)、実際の16ビット終了ステータスワードでは次のようになります。

$ perl -MPOSIX -e 'fork || raise SIGTERM; wait; printf "%016b\n", $?'
0000000000001111
$ perl -E 'say 0b1111'
15

したがって、Perlは呼び出しから直接返された16ビットの単語を使用し、wait(2)Unixシェルはそれを別の形式に変換します。使用する言語に応じて、Cの規則に従い、「終了コードを表示するには左に移動する」などの操作を実行する必要があります(通常、これをサポートするマクロやその他の呼び出しがあります。詳細については、ドキュメントを参照してください)。あるいは、シェルダメージ値を使用している場合は、「128を引いて信号番号を見つけます」。

追加のポイントを取得するには、コアファイルを生成するプログラムを作成し、終了ステータスワードがどのように見えるかを確認するか、他の信号番号などを試してください。

状態語の使用方法

使用されなくなったり、そうでなくなる可能性があるさまざまな規則があります。たとえば、sysexits.hこれらのコードのいくつかは電子メール配信システムにとって重要であり(歴史的にsendmail)、特定のコードを使用して「再試行」一時的な失敗を示すことがあります(inは4xxです)。 「拒否し、再試行」の代わりにSMTPのコード)。この電子メールを返信してください(5xx)を選択すると、メールprocmail配信エージェントソフトウェア(または同様のソフトウェア)でそれへの参照を表示できます。

$ grep EX_TEMPFAIL /usr/include/sysexits.h
 *      EX_TEMPFAIL -- temporary failure, indicating something that
#define EX_TEMPFAIL     75      /* temp failure; user is invited to retry */

そうでなければ、0通常は「良い」を意味します(ただし、ゼロ以外のコードを設定しないと、プログラムは失敗する可能性があるため、買い手は注意してください!)。 「いいえ」は0「悪い」を意味します(ただし、正確に意味するものは異なります。一時的な欠陥、騒音が無視される、状況が悪い可能性があります)。特定の終了コードはサイト、ベンダー、またはソフトウェアに固有の意味を持つことができます。これらの特定のコードは記録されても記録されなくてもよい。ページには、次のような概要を生成するman一般的なマクロがあることがよくあります。.Ex -std

EXIT STATUS
     The foo utility exits 0 on success, and >0 if an error occurs.

または、必要に応じてより具体的な文書を提供してください(ソフトウェアがよく文書化されている場合)。多くのソフトウェアが正しく文書化されていません。

これはいつ重要ですか?

モニターまたはテストサーバー実際、「ゼロ以外の古いシャットダウン」とsegfaultまたはコアダンプのために突然終了するプログラムを区別する必要があるかもしれません。あるいは、segfaultが特定のテストに期待される値であり、そのようなことが起こらない場合は一般的ではありません。 。ゼロだけを報告するかゼロ以外であると報告する監視またはテストは、貴重なデバッグ情報を無視します。

上記のように、SMTPサーバーは、ローカル配信エージェントによって返された正確な終了ステータスワードに従ってさまざまな操作を実行します。ハードバウンスは、サーバーが再試行できる一時的な配信失敗とはかなり異なります。

関連情報