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 $?
друкував би код стільника лише тоді, коли він дорівнює нулю ...