プロセスは、整数引数を使用して_exit()
システム呼び出し(Linuxの場合も参照exit_group()
)を呼び出して、終了コードを親に報告できます。整数ですが、親は最下位8ビットのみを使用できます(Linuxでなくても、親のSIGCHLDを使用してそのコードを取得する場合をwaitid()
除く)。
通常、親はを実行するwait()
か、子waitpid()
のステータスを整数として取得します(ただしwaitid()
、多少異なるセマンティクスを使用することもできます)。
LinuxおよびほとんどのUnicesでは、プロセスが正常に終了した場合、そのステータス番号のビット8〜15にはに渡される終了コードが含まれexit()
ます。そうでない場合、最下位7ビット(0〜6)に信号番号が含まれ、コアがダンプされた場合はビット7が設定されます。
perl
の$?
例では、次のように設定された番号が含まれていますwaitpid()
。
$ perl -e 'system q(kill $$); printf "%04x\n", $?'
000f # killed by signal 15
$ perl -e 'system q(kill -ILL $$); printf "%04x\n", $?'
0084 # killed by signal 4 and core dumped
$ perl -e 'system q(exit $((0xabc))); printf "%04x\n", $?'
bc00 # terminated normally, 0xbc the lowest 8 bits of the status
Bourneのようなシェルは、最後の実行コマンドの終了ステータスを独自の$?
変数にします。ただし、によって返される数値は直接含まれておらずwaitpid()
、その上に変換が含まれており、シェルによって異なります。
すべてのシェルに共通するのは、プロセスが正常に終了した場合$?
に、終了コードの最下位8ビット(に渡される番号exit()
)が含まれることです。
異なるのは、プロセスがシグナルによって終了したときです。すべての場合、およびPOSIXで必要な場合、この数は128を超えます。POSIXは値が何であるかを指定しません。しかし実際には、私が知っているすべてのBourne風のシェルでは、の最下位7ビットに$?
信号番号が含まれます。しかし、n
信号番号はどこですか、
灰で、zshの、pdkshのは、bash、Bourneシェルは、$?
あります128 + n
。つまり、これらのシェルでは、$?
of を取得した場合129
、プロセスが終了したためであるのexit(129)
か、シグナルによって終了したのか1
(HUP
ほとんどのシステムで)わかりません。しかし、理論的には、シェルは、終了するときに、デフォルトで最後に終了したコマンドの終了ステータスを返すということです。必ず$?
255を超えないようにすることで、一貫した終了ステータスを得ることができます。
$ bash -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
bash: line 1: 16720 Terminated sh -c "kill \$\$"
8f # 128 + 15
$ bash -c 'sh -c "kill \$\$"; exit'; printf '%x\n' "$?"
bash: line 1: 16726 Terminated sh -c "kill \$\$"
8f # here that 0x8f is from a exit(143) done by bash. Though it's
# not from a killed process, that does tell us that probably
# something was killed by a SIGTERM
ksh93
、$?
です256 + n
。つまり、$?
あなたの価値から、強制終了されたプロセスと強制終了されていないプロセスを区別できます。の新しいバージョンはksh
、終了時に$?
255より大きい場合、同じ終了ステータスを親に報告できるようにするために、同じシグナルで自身を強制終了します。それは良いアイデアのように聞こえksh
ますが、それはプロセスがコア生成シグナルによって強制終了された場合、余分なコアダンプを生成する(他のコアダンプを上書きする可能性がある)ことを意味します。
$ ksh -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
ksh: 16828: Terminated
10f # 256 + 15
$ ksh -c 'sh -c "kill -ILL \$\$"; exit'; printf '%x\n' "$?"
ksh: 16816: Illegal instruction(coredump)
Illegal instruction(coredump)
104 # 256 + 15, ksh did indeed kill itself so as to report the same
# exit status as sh. Older versions of `ksh93` would have returned
# 4 instead.
あなたも言うことができる場合にはバグがあることがありますksh93
場合でも、自分自身を殺す$?
から来ているreturn 257
機能によって行わ:
$ ksh -c 'f() { return "$1"; }; f 257; exit'
zsh: hangup ksh -c 'f() { return "$1"; }; f 257; exit'
# ksh kills itself with a SIGHUP so as to report a 257 exit status
# to its parent
yash
。yash
妥協を提供します。を返します256 + 128 + n
。つまり、強制終了されたプロセスと適切に終了したプロセスを区別することもできます。そして、退出すると、128 + n
自殺することなく報告することができます。
$ yash -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
18f # 256 + 128 + 15
$ yash -c 'sh -c "kill \$\$"; exit'; printf '%x\n' "$?"
8f # that's from a exit(143), yash was not killed
の値から信号を取得するための$?
ポータブルな方法は、kill -l
次のとおりです。
$ /bin/kill 0
Terminated
$ kill -l "$?"
TERM
(移植性のために、シグナル番号は使用せず、シグナル名のみを使用してください)
非ボーンフロントでは:
たぶん完全を期すために、我々は言及すべきzsh
さん$pipestatus
とbash
の$PIPESTATUS
最後のパイプラインの構成部品の終了ステータスが含まれている配列を。
また、完全を期すために、シェル関数とソースファイルについては、デフォルトでは関数は最後のコマンド実行の終了ステータスで戻りますが、return
組み込み関数で明示的に戻りステータスを設定することもできます。ここにいくつかの違いがあります。
bash
そしてmksh
(R41ので、回帰^ Wchangeが明らかに意図的に導入は)8ビットに(正または負)の数を切り捨てます。だから、例えばreturn 1234
設定されます$?
し210
、return -- -1
設定します$?
255。
zsh
及びpdksh
(以外の誘導体mksh
)は、任意の符号付き32ビットの10進数を可能にする(-2 31 2 31 -1)(と32ビットに番号を切り捨て)。
ash
yash
0〜2 31 -1の正の整数を許可し、その中の任意の数のエラーを返します。
ksh93
そのままreturn 0
にreturn 320
設定$?
しますが、それ以外の場合は8ビットに切り捨てます。すでに述べたように、256から320の間の数値を返すと、ksh
終了時に自分自身を殺す可能性があることに注意してください。
rc
そしてes
何でもリストを返すことができます。
また、いくつかのシェルもの特殊な値を使用することに注意してください$?
/ $status
、のようなプロセスの終了ステータスではありませんいくつかのエラー状態を報告し127
たり126
するためにコマンドが見つからないか、実行可能ではない(ソースファイルまたは構文エラー)...
killall myScript
作品、したがって、killallの戻り値(スクリプトの戻り値ではありません!)は0です。kill -x $$
[xはシグナル番号であり、通常$$はシェルによってそのスクリプトのPIDに展開されます(sh、bash、 ...)] スクリプト内で、出口コアが何であるかをテストします。