終了ステータスが 0 の場合、プロセスは Linux で正しく完了したと見なされます。
セグメンテーション違反が原因で終了ステータスが 11 になることがよくありますが、これが単に私が働いている慣習なのか (そのように失敗したアプリはすべて内部のものでした)、それとも標準なのかはわかりません。
Linux のプロセスに標準の終了コードはありますか?
終了ステータスが 0 の場合、プロセスは Linux で正しく完了したと見なされます。
セグメンテーション違反が原因で終了ステータスが 11 になることがよくありますが、これが単に私が働いている慣習なのか (そのように失敗したアプリはすべて内部のものでした)、それとも標準なのかはわかりません。
Linux のプロセスに標準の終了コードはありますか?
いつものように、高度な Bash スクリプト ガイドには優れた情報があります: (これは別の回答にリンクされていますが、非正規の URL にリンクされています。)
1: 一般的なエラーのキャッチオール
2:シェル ビルトインの誤用 (Bash のドキュメントによる)
126: 呼び出されたコマンドは実行できません
127: "コマンドが見つかりません"
128: 終了する引数が無効です
128+n: 致命的なエラー シグナル "n"
255:終了しますステータスが範囲外です (exit は 0 から 255 の範囲の整数引数のみを取ります)
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)
& coからのリターンでは、8 ビットのリターン コードと 8 ビットの kill シグナルの番号が混合されて 1 つの値になります。.
#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'; エコー $? 42 $ sh -c 'kill -SEGV $$'; エコー $? セグメンテーション違反 139 $ expr 139 - 128 11
これ以外のものが表示されている場合、プログラムには通常どおりにSIGSEGV
呼び出すシグナル ハンドラーが含まれている可能性がexit
あり、実際にはシグナルによって強制終了されていません。(プログラムは、SIGKILL
と以外の任意のシグナルを処理することを選択できますSIGSTOP
。)
'1' >>> 一般エラーのキャッチオール
'2' >>> シェル組み込み関数の誤用 (Bash のドキュメントによると)
'126' >>> 呼び出されたコマンドを実行できません
'127' >>>「コマンドが見つかりません」
'128' >>> 終了する引数が無効です
'128+n' >>>致命的なエラー信号 "n"
'130' >>> Control-C で終了するスクリプト
'255' >>>終了ステータスが範囲外です
これはバッシュ用です。ただし、他のアプリケーションの場合は、異なる終了コードがあります。
終了ステータス 2 を正しく説明している古い回答はありません。彼らの主張とは反対に、ステータス 2 は、不適切に呼び出されたときにコマンド ライン ユーティリティが実際に返すものです。(はい、答えは 9 年前のもので、何百もの賛成票があり、それでも間違っている可能性があります。)
これは、通常の終了、つまりシグナルによるものではない、実際の長年にわたる終了ステータスの規則です。
たとえば、diff
比較するファイルが同一の場合は 0 を返し、異なる場合は 1 を返します。長年の慣習により、UNIX プログラムは、誤って呼び出された場合 (未知のオプション、間違った数の引数など) に終了ステータス 2 を返します。 たとえばdiff -N
、grep -Y
ordiff a b c
はすべて$?
2 に設定されます。 1970 年代の Unix 黎明期。
受け入れられた回答は、コマンドがシグナルによって終了したときに何が起こるかを説明しています。簡単に言うと、キャッチされなかったシグナルによる終了は終了ステータスになります128+[<signal number>
。たとえば、SIGINT
( signal 2 ) による終了は、終了ステータス 130 になります。
いくつかの回答では、終了ステータス 2 を「bash ビルトインの誤用」と定義しています。これは、 bash (または bash スクリプト) がステータス 2 で終了した場合にのみ適用されます。これは、不適切な使用エラーの特殊なケースと考えてください。
では、最も一般的な回答でsysexits.h
言及されているように、終了ステータス(「コマンド ライン使用エラー」) は 64 と定義されています。 )。ソース コードを注意深く読むと、実際の使用法を反映したものではなく、野心的なものであることがわかります。EX_USAGE
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 年) の一般的な慣行を反映していませんが、意図的にそれと互換性がありませんでした。もっと残念です。
成功を意味する 0 を除いて、標準の終了コードはありません。ゼロ以外でも、必ずしも失敗を意味するわけではありません。
stdlib.h はEXIT_FAILURE
1 とEXIT_SUCCESS
0 を定義していますが、それだけです。
11 は、segfault が発生した場合にカーネルがプロセスを強制終了するために使用するシグナル番号であるため、segfault の 11 は興味深いものです。カーネルまたはシェルのいずれかに、それを終了コードに変換する何らかのメカニズムがある可能性があります。
sysexits.hには、標準の終了コードのリストがあります。それは少なくとも1993年にさかのぼると思われ、Postfixのようないくつかの大きなプロジェクトがそれを使用しているので、それが進むべき道だと思います。
OpenBSDのマニュアルページから:
style(9)によると、プログラムの終了時に障害状態を示すために任意の値を指定してexit(3)を呼び出すことはお勧めできません。代わりに、sysexitsからの事前定義された終了コードを使用する必要があります。これにより、プロセスの呼び出し元は、ソースコードを検索しなくても、障害クラスに関する大まかな見積もりを取得できます。
最初の概算では、0 は成功、ゼロ以外は失敗、1 は一般的な失敗、1 より大きいものは特定の失敗です。false と test の些細な例外 (どちらも成功すると 1 を返すように設計されています) を除いて、他にもいくつかの例外を見つけました。
より現実的には、0 は成功または失敗の可能性があることを意味し、1 は一般的な失敗または成功の可能性があることを意味し、1 と 0 の両方が成功のために使用される場合、2 は一般的な失敗を意味します。
diff コマンドは、比較したファイルが同一の場合は 0、異なる場合は 1、バイナリが異なる場合は 2 を返します。2 も失敗を意味します。less コマンドは、引数の指定に失敗しない限り、失敗に対して 1 を返します。引数の指定に失敗した場合、失敗しても 0 で終了します。
more コマンドと spell コマンドは、失敗が許可の拒否、存在しないファイル、またはディレクトリの読み取り試行の結果でない限り、失敗に対して 1 を返します。これらのいずれの場合でも、失敗しても 0 で終了します。
次に、expr コマンドは、出力が空の文字列またはゼロでない限り、成功を示す 1 を返します。この場合、0 は成功です。2と3は失敗です。
そして、成功か失敗かが曖昧な場合があります。grep がパターンを見つけられない場合は 1 を終了しますが、真の失敗 (許可が拒否されたなど) の場合は 2 を終了します。Klist は、チケットが見つからない場合も 1 で終了しますが、これは、grep がパターンを見つけられない場合や、空のディレクトリを ls する場合よりも実際には失敗ではありません。
そのため、残念ながら、非常に一般的に使用される実行可能ファイルであっても、UNIX の力は論理的なルールのセットを強制していないようです。
プログラムは 16 ビットの終了コードを返します。プログラムがシグナルで強制終了された場合、上位バイトには使用されたシグナルが含まれます。それ以外の場合、下位バイトはプログラマーによって返された終了ステータスです。
その終了コードはどのようにステータス変数 $ に割り当てられますか? その後、シェル次第です。Bash はステータスの下位 7 ビットを保持し、128 + (シグナル番号) を使用してシグナルを示します。
プログラムの唯一の「標準」規則は、成功の場合は 0、エラーの場合はゼロ以外です。使用される別の規則は、エラー時に errno を返すことです。
別のポスターで述べたように、標準のUnix終了コードはsysexits.hによって定義されています。同じ終了コードがPocoなどのポータブルライブラリで使用されています-それらのリストは次のとおりです。
http://pocoproject.org/docs/Poco.Util.Application.html#16218
信号11はSIGSEGV(セグメンテーション違反)信号であり、戻りコードとは異なります。このシグナルは、悪いページアクセスに応答してカーネルによって生成され、プログラムを終了させます。シグナルのリストは、シグナルのマニュアルページにあります(「mansignal」を実行してください)。
Linux が 0 を返すと、成功を意味します。それ以外はすべて失敗を意味し、各プログラムには独自の終了コードがあるため、すべてをリストすると非常に長くなります... !
エラー コード 11 については、実際にはセグメンテーション フォールト番号であり、プログラムが割り当てられていないメモリ ロケーションにアクセスしたことを意味します。