cmd && echo "$?"
これは、必然的にゼロecho
のみを出力するため、機能しません(前のコマンドが正常に完了したときにのみ実行されます)。
ここにあなたのための短いシェル関数があります:
tellexit () {
"$@"
local err="$?"
printf 'exit code\t%d\n' "$err" >/dev/tty
return "$err"
}
これは、コマンドと同様の方法で、指定されたコマンドの終了コードを出力time
します。
$ tellexit echo "hello world"
hello world
exit code 0
$ tellexit false
exit code 1
リダイレクトすることによって、printf
に/dev/tty
機能して、我々はまだ使用することができtellexit
、当社の標準出力またはエラーストリームにジャンクを取得せずにリダイレクトして:
$ tellexit bash -c 'echo hello; echo world >&2' >out 2>err
exit code 0
$ cat out
hello
$ cat err
world
終了コードを変数に保存することにより、呼び出し元に終了コードを返すことができます。
$ tellexit false || echo 'failed'
exit code 1
failed
同じ関数のより洗練されたバージョンは、終了コードが128より大きい場合にコマンドを強制終了したシグナルも出力します(つまり、シグナルが原因で終了したことを意味します)。
tellexit () {
"$@"
local err="$?"
if [ "$err" -gt 128 ]; then
printf 'exit code\t%d (%s)\n' "$err" "$(kill -l "$err")" >/dev/tty
else
printf 'exit code\t%d\n' "$err" >/dev/tty
fi
return "$err"
}
テスト:
$ tellexit sh -c 'kill $$'
exit code 143 (TERM)
$ tellexit sh -c 'kill -9 $$'
Killed
exit code 137 (KILL)
(これにlocal
はash
/ pdksh
/ bash
/ zsh
が必要ですがtypeset
、他のいくつかのシェルでも理解できるように変更することもできます。)
sleep 1 && echo $?
スリーパーセルのコードはゼロの場合にのみ出力されます...