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
to /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 $?
напечатал бы код спящей ячейки, только когда она равна нулю ...