web-dev-qa-db-ja.com

bashスクリプトの最後の終了コード

私はbashスクリプトの最後にある終了コードの意味について混乱しています:終了コード0は正常に終了したことを意味し、さらに多くの終了コード番号があることを知っています(間違っていない場合は127)。

私の質問は、スクリプトの最後に終了コード0が表示されたときのことですが、スクリプトが失敗したり、別の意味がある場合でも、終了コードを強制的に0にしますか?

23
Busted

組み込みコマンドexitはシェルを終了します( Bashのリファレンス から):

exit [n]
シェルを終了し、nのステータスをシェルの親に返します。 nを省略すると、終了ステータスは最後に実行されたコマンドのステータスになります。 EXITのトラップは、シェルが終了する前に実行されます。

ファイルの最後まで実行すると終了し、最後のコマンドの戻りコードが返されるため、最後のexit 0は、前のコマンドの終了ステータスに関係なく、スクリプトを成功ステータスで終了します。 (つまり、スクリプトが最後のexitに到達すると想定します。)スクリプトの最後にtrueまたは:を使用して、終了コード0を取得することもできます。

もちろん、多くの場合、exitの内側からifを使用して、スクリプトを途中で終了します。

これらは1を出力するはずです($?には、前のコマンドで返された終了コードが含まれています)。

sh -c "false" ; echo $?
sh -c "false; exit" ; echo $?

これは0を出力するはずですが、

sh -c "false; exit 0" ; echo $?

exitの実行時にスクリプトが「失敗する」という概念が理にかなっているかどうかはわかりません。スクリプトによって実行された一部のコマンドが失敗しても、スクリプト自体は成功する可能性があるためです。何が成功で何が成功しないかを決定するのは、スクリプトの作成者次第です。

また、終了コードの標準範囲は0..255です。 127を超えるコードは、シグナルによって終了したプロセスを示すためにシェルによって使用されますが、通常の方法で返すことができます。 waitシステムコールは実際にはより広い値を返し、残りはオペレーティングシステムによって設定されたステータスビットを含みます。

23
ilkkachu

0は成功を意味し、正の整数は失敗を意味します。エラーコードは255種類ありますが、126以上の値は、プログラムが起動できなかった(126または127)か、シグナルによって強制終了された(129以上の)ことを示すために予約されています。詳細については、 プロセスが終了したときのデフォルトの終了コード および bash関数/スクリプトで使用できる戻り値/終了値 を参照してください。

シェルスクリプトの終了ステータスは、スクリプトが実行した最後のコマンドの終了ステータスです。だから例えば

#!/bin/sh
somecommand

somecommandの終了ステータスを返しますが、

#!/bin/sh
somecommand
exit 0

somecommandの戻り値に関係なく、0を返します。この2番目のスクリプトも記述できます

#!/bin/sh
somecommand
true

スクリプトの最後にexit 0を置いても、必ずしも0が返されるとは限りません。これにより、スクリプトの最後に達したときにのみ0が返されます。たとえば、次のスクリプトは常に3を返します。

#!/bin/sh
exit 3
exit 0

次のスクリプトは、構文エラーに関するメッセージを表示するだけでなく、常にエラーコードも返します。

#!/bin/sh
}
exit 0

次のスクリプトは、最初の引数に応じて1または0を返します。

#!/bin/sh
if [ "$1" = "foo" ]; then
  exit 1
fi
exit 0

次のスクリプトは、somecommandが失敗した場合にset -eによってスクリプトが終了するため、somecommandのステータスを返します。

#!/bin/sh
set -e
somecommand
exit 0