Linuxでは、終了ステータスが0の場合、プロセスは正しく完了したと見なされます。
セグメンテーション違反が11の終了ステータスになることがよくあるのを見てきましたが、これが単に私が作業する規則(そのように失敗したアプリ)が標準であるのか、それとも標準であるのかはわかりません。
Linuxのプロセスに標準の終了コードはありますか?
Linuxでは、終了ステータスが0の場合、プロセスは正しく完了したと見なされます。
セグメンテーション違反が11の終了ステータスになることがよくあるのを見てきましたが、これが単に私が作業する規則(そのように失敗したアプリ)が標準であるのか、それとも標準であるのかはわかりません。
Linuxのプロセスに標準の終了コードはありますか?
回答:
wait(2)
&coからの戻り時に、戻りコードの8ビットとキリング信号の数の8ビットが単一の値に混合されます。。
#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
。)
いつものように、Advanced Bash Scripting Guideにはすばらしい情報があります(これは別の回答でリンクされていましたが、非正規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 */
man sysexits
sysexits.h
どこにありますか?manページ誰もが参照し続けるだけの散文です。たとえばEX_OK
、他のコードのように規範的な方法でそれを参照しますが実際には定義しません。不足しているものは他にありますか?
「1」 >>>一般的なエラーのキャッチオール
「2」 >>>シェル組み込みの誤用(Bashのドキュメントによる)
「126」 >>>呼び出されたコマンドは実行できません
「127」 >>> "コマンドが見つかりません"
「128」 >>>終了する引数が無効です
「128 + n」 >>>致命的なエラー信号 "n"
'130' >>>スクリプトはControl-Cで終了しました
'255' >>>範囲外の終了ステータス
これはbash用です。ただし、他のアプリケーションでは、異なる終了コードがあります。
古い回答では、終了ステータス2を正しく説明していません。彼らが主張することに反して、ステータス2は、不適切に呼び出されたときにコマンドラインユーティリティが実際に返すものです。(はい、答えは9歳になる可能性があり、何百もの賛成投票があり、それでも間違いがあります。)
これは、正常終了、つまりシグナルによるものではない、長期にわたる終了ステータス規則です。
たとえば、diff
比較するファイルが同一の場合は0を返し、異なる場合は1を返します。UNIXプログラムは、長年の慣例により、誤って呼び出された場合に終了ステータス2を返します(不明なオプション、引数の数など) 。たとえばdiff -N
、grep -Y
またはdiff a b c
すべて$?
が2に設定されます。これは、 Unixの初期の1970年代。
受け入れ答えは、コマンドがされたときに何が起こるかを説明し、信号により終了します。簡単に言えば、キャッチされていない信号による終了は、終了ステータスになります128+[<signal number>
。例えば、SIGINT
(シグナル2)による終了は、終了ステータス130になります。
いくつかの回答では、終了ステータス2を「bashビルトインの誤用」と定義しています。これは、bash(またはbashスクリプト)がステータス2で終了する場合にのみ適用されます。不正な使用エラーの特殊なケースと考えてください。
でsysexits.h
に述べたように、最も人気のある答え、終了ステータスはEX_USAGE
(「コマンドラインの使用方法の誤り」)64になるように定義される。しかし、これは現実を反映していない:私は知りません任意の一般的なUNIXユーティリティ間違った呼び出しの戻り64は、(例は歓迎していること)。ソースコードを注意深く読むと、それ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年)の一般的な慣習を反映していないが、意図的にそれと互換性がなかった。もっと残念だ。
more
、ターミナルモードをリセットし、ステータス0で終了します(試すことができます)。
sysexits.hには、標準の終了コードのリストがあります。それは少なくとも1993年にさかのぼるようで、Postfixのようないくつかの大きなプロジェクトがそれを使用しているので、私はそれが進むべき道だと思います。
OpenBSDのmanページから:
style(9)によると、プログラムの終了時にエラー状態を示すために任意の値でexit(3)を呼び出すことはお勧めできません。代わりに、sysexitsからの事前定義された終了コードを使用する必要があります。これにより、プロセスの呼び出し元は、ソースコードを調べることなく、障害クラスに関する大まかな見積もりを取得できます。
最初の近似では、0は成功、0以外は失敗、1は一般的な失敗、1より大きいものは特定の失敗です。falseとtestの些細な例外は別として、どちらも成功すると1を与えるように設計されていますが、他にもいくつか例外があります。
より現実的には、0は成功またはおそらく失敗を意味し、1は一般的な失敗またはおそらく成功を意味し、2は1と0の両方が成功に使用された場合の一般的な失敗を意味しますが、おそらく成功もします。
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の能力。
別の投稿者が述べたように、標準のUnix終了コードはsysexits.hによって定義されています。同じ終了コードがPocoなどのポータブルライブラリで使用されます-以下にそれらのリストを示します。
http://pocoproject.org/docs/Poco.Util.Application.html#16218
信号11は、戻りコードとは異なるSIGSEGV(セグメント違反)信号です。このシグナルは、不良ページアクセスに応答してカーネルによって生成され、プログラムを終了させます。シグナルのリストは、シグナルのmanページ(「man signal」を実行)にあります。
Linuxが0を返すと、成功を意味します。それ以外の場合は失敗を意味し、各プログラムには独自の終了コードがあるため、それらすべてをリストするのはかなり時間がかかります...!
11個のエラーコードについては、実際にはセグメンテーションフォールト番号です。これは、ほとんどの場合、プログラムが割り当てられていないメモリロケーションにアクセスしたことを意味します。