'1' :一般的なエラーのキャッチオール
'2' :シェル組み込みの誤用 (Bash のドキュメントによる)
'126' :呼び出されたコマンドは実行できません
'127' :"コマンドが見つかりません"
'128' :終了する引数が無効です
'128+n' :致命的なエラー信号 "n"
'130' :スクリプトは Ctrl で終了します + C
'255' :範囲外の終了ステータス
これはバッシュ用です。ただし、他のアプリケーションの場合は、異なる終了コードがあります。
パート 1:高度な Bash スクリプト作成ガイド
いつものように、高度な Bash スクリプト ガイドには優れた情報があります:(これは別の回答にリンクされていましたが、正規の URL ではありません)。
<ブロック引用>
1: 一般的なエラーのキャッチオール
2: シェル組み込みの誤用 (Bash のドキュメントによると)
126: 呼び出されたコマンドを実行できません
127: "コマンドが見つかりません"
128: 終了する引数が無効です
128+n: 致命的なエラー信号「n」
255: 終了ステータスが範囲外です (終了は 0 ~ 255 の範囲の整数引数のみを取ります)
パート 2:sysexits.h
ABSG は sysexits.h
を参照します .
Linux の場合:
$ find /usr -name sysexits.h
/usr/include/sysexits.h
$ cat /usr/include/sysexits.h
/*
* Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved.
(A whole bunch of text left out.)
#define EX_OK 0 /* successful termination */
#define EX__BASE 64 /* base value for error messages */
#define EX_USAGE 64 /* command line usage error */
#define EX_DATAERR 65 /* data format error */
#define EX_NOINPUT 66 /* cannot open input */
#define EX_NOUSER 67 /* addressee unknown */
#define EX_NOHOST 68 /* host name unknown */
#define EX_UNAVAILABLE 69 /* service unavailable */
#define EX_SOFTWARE 70 /* internal software error */
#define EX_OSERR 71 /* system error (e.g., can't fork) */
#define EX_OSFILE 72 /* critical OS file missing */
#define EX_CANTCREAT 73 /* can't create (user) output file */
#define EX_IOERR 74 /* input/output error */
#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
#define EX_PROTOCOL 76 /* remote error in protocol */
#define EX_NOPERM 77 /* permission denied */
#define EX_CONFIG 78 /* configuration error */
#define EX__MAX 78 /* maximum listed value */
wait(2)
からの戻り時に、8 ビットのリターン コードと 8 ビットの kill シグナルの番号が混合されて 1 つの値になります。 &co..
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
int main() {
int status;
pid_t child = fork();
if (child <= 0)
exit(42);
waitpid(child, &status, 0);
if (WIFEXITED(status))
printf("first child exited with %u\n", WEXITSTATUS(status));
/* prints: "first child exited with 42" */
child = fork();
if (child <= 0)
kill(getpid(), SIGSEGV);
waitpid(child, &status, 0);
if (WIFSIGNALED(status))
printf("second child died with %u\n", WTERMSIG(status));
/* prints: "second child died with 11" */
}
どのように終了ステータスを決定していますか?従来、シェルは 8 ビットの戻りコードのみを保存しますが、プロセスが異常終了した場合は上位ビットを設定します。
$ sh -c 'exit 42'; echo $? 42 $ sh -c 'kill -SEGV $$'; echo $? Segmentation fault 139 $ expr 139 - 128 11
これ以外のものが表示される場合、プログラムにはおそらく SIGSEGV
があります exit
を呼び出すシグナルハンドラ 通常、実際にはシグナルによって殺されることはありません。 (プログラムは SIGKILL
以外の任意のシグナルを処理することを選択できます および SIGSTOP
.)
終了ステータス 2 を正しく説明している古い回答はありません。彼らの主張に反して、ステータス 2 は、不適切に呼び出されたときにコマンド ライン ユーティリティが実際に返すものです。 (はい、答えは 9 年前のもので、何百もの賛成票があり、それでも間違っている可能性があります。)
これは、通常の終了、つまりシグナルによるものではない、実際の長年にわたる終了ステータスの規則です:
- 終了ステータス 0:成功
- 終了ステータス 1:プログラムで定義されている「失敗」
- 終了ステータス 2:コマンドライン使用エラー
例:diff
比較するファイルが同一の場合は 0 を返し、異なる場合は 1 を返します。長年の慣例により、UNIX プログラムは誤って呼び出された場合 (不明なオプション、間違った数の引数など) に終了ステータス 2 を返します。 例:diff -N
、 grep -Y
または diff a b c
すべて $?
になります 2 に設定されています。これは、1970 年代の Unix の初期からの慣例です。
受け入れられた回答は、コマンドがシグナルによって終了されたときに何が起こるかを説明しています。 簡単に言えば、キャッチされないシグナルによる終了は終了ステータス 128+[<signal number>
になります .例:SIGINT
による終了 (シグナル 2) 終了ステータス 130 になります。
メモ
<オール>いくつかの回答では、終了ステータス 2 を「bash ビルトインの誤用」と定義しています。これは、bash の場合にのみ適用されます (または bash スクリプト) はステータス 2 で終了します。これは、不適切な使用エラーの特殊なケースと考えてください。
sysexits.h
で 、最も人気のある回答で言及されている終了ステータス EX_USAGE
(「コマンド ライン使用エラー」) は 64 と定義されています。しかし、これは現実を反映していません。 誤った呼び出しで 64 を返す一般的な Unix ユーティリティ (例を歓迎)。ソース コードを注意深く読むと、sysexits.h
であることがわかります。 実際の使用法を反映したものではなく、希望的なものです:
* This include file attempts to categorize possible error * exit statuses for system programs, notably delivermail * and the Berkeley network. * Error numbers begin at EX__BASE [64] to reduce the possibility of * clashing with other exit statuses that random programs may * already return.
言い換えれば、これらの定義は当時 (1993 年) の一般的な慣行を反映していませんが、意図的にそれと互換性がありませんでした。もっと残念です。