終了ステータスは重要。
じつはあまり顧みられない、終了ステータスですが「条件分岐」の条件になってる。そのことは以前書きました。今回はこの「異常終了」のコードを詳しく見ていきます。
bashでは次のように定義されています。
$? == 0
が正常終了$?> 0
がエラー終了
になります。ただし、bashでは汎用的なエラーコードの指針が決まっています、またエラー終了はコマンドごとに意味があります。
Bashにおける終了コードの意味
マニュアルの抜粋からです。Exit Codes With Special Meanings
http://www.tldp.org/LDP/abs/html/exitcodes.html#EXITCODESREF
数字 | 意味 | コメント |
---|---|---|
1 | 各種エラー | 何でもかんでも放り込む。ゼロ除算など.letの計算不能など |
2 | 使用方法の誤り | ユーザーの所有権エラーなどが含まれる。 |
126 | 実行権限エラー | 実行権(x)のエラー |
127 | コマンドが無い | typo、コマンド見つからないとき |
130 | Ctrl+C で止めた | Ctrl+C(シグナル2)で止めると 128+2で130 になる |
bashではエラーを 1-255
の数値で返すことになっています。その返す数値に上記の表の指針が定められています。
コマンドごとに終了コードに意味をもたせることがある。
bashの解釈とは別に、エラー終了コードに意味を与えているコマンドが有ります。
幾つかのコマンドについて見ておきましょう。とくにgrep は行が見つからない「正常終了」も「1」を返すので注意が必要ですね。
grep の場合
EXIT STATUS The grep utility exits with one of the following values: 0 One or more lines were selected. 1 No lines were selected. >1 An error occurred.
ping の場合
EXIT STATUS The ping utility exits with one of the following values: 0 At least one response was heard from the specified host. 2 The transmission was successful but no responses were received. any other value An error occurred. These values are defined in <sysexits.h>.
ls の場合
DIAGNOSTICS The ls utility exits 0 on success, and >0 if an error occurs.
コマンドごとの意味
すべてをここに書き出すのは到底無理なのです。が、man で調べられます。
先程の例のgrep
であれば、man grep
して STATUS
をマニュアル内部を探せば出てきます。ぜひ一度見てみてください。
exit ステータスコードを 0 以下 255 以上にするとどうなるのか
私達が関数やコマンドファイルを作るの時の戻り値を自由に決められるとは言え、無茶をするとどうなるのでしょうか。見ておきたいと思います。ここで使うexit コマンドは関数内部で使われ、終了しステータスコードを返すために使われます。関数内部であれば return とほぼ同じ意味ですが、 exit はそれより強くその場で実行を止めます。
takuya@Desktop$ ( exit 255 ) ; echo $? 255 takuya@Desktop$ ( exit 256 ) ; echo $? 0 takuya@Desktop$ ( exit -1 ) ; echo $? 255
あ・・・・0じゃないのにゼロになる・・・
256以上の終了コードは、 mod 256 で丸められます。 なのであまり大きいステータスコードを使っても意味が無いと思います。
takuya@Desktop$ ( exit 512 ) ; echo $? 0 takuya@Desktop$ ( exit 513 ) ; echo $? 1 takuya@Desktop$ ( exit 514 ) ; echo $? 2
参考資料
http://www.tldp.org/LDP/abs/html/exitcodes.html#EXITCODESREF
http://qiita.com/Linda_pp/items/1104d2d9a263b60e104b
ご指摘感謝です!
https://t.co/6xr08pPT1J if が終了ステータス 0 かどうかで分岐するのは正しいけど、終了ステータス0以外が異常終了を示しているかどうかはコマンドによりけりかと。普通に使う test([])コマンドは true/false 的意味でステータスを返すし
— てらまこ (@teramako) December 29, 2016
*1:マニュアルによると128/128+n があるのですが。128 + invalid signal と 128 invalid exit code は、再現できなかったため記述を省略しました。kill 自体が不能でエラーになる。なのと、exit 'a' は数字引数にしろと怒られて終了コードが1だった。