cmd && echo "$?"
würde nicht funktionieren, da es notwendigerweise nur Nullen drucken echo
würde (die würden nur nach erfolgreichem Abschluss des vorhergehenden Befehls ausgeführt).
Hier ist eine kurze Shell-Funktion für Sie:
tellexit () {
"$@"
local err="$?"
printf 'exit code\t%d\n' "$err" >/dev/tty
return "$err"
}
Dadurch wird der Exit-Code des angegebenen Befehls auf ähnliche Weise wie beim time
Befehl gedruckt.
$ tellexit echo "hello world"
hello world
exit code 0
$ tellexit false
exit code 1
Durch Umleiten des printf
to /dev/tty
in die Funktion können wir weiterhin tellexit
Umleitungen verwenden, ohne dass Junk in unseren Standardausgabe- oder Fehlerströmen auftritt:
$ tellexit bash -c 'echo hello; echo world >&2' >out 2>err
exit code 0
$ cat out
hello
$ cat err
world
Durch Speichern des Exit-Codes in einer Variablen können wir ihn an den Aufrufer zurückgeben:
$ tellexit false || echo 'failed'
exit code 1
failed
Eine schickere Version derselben Funktion gibt auch das Signal aus, das den Befehl beendet hat, wenn der Exit-Code größer als 128 ist (was bedeutet, dass er aufgrund eines Signals beendet wurde):
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"
}
Testen:
$ tellexit sh -c 'kill $$'
exit code 143 (TERM)
$ tellexit sh -c 'kill -9 $$'
Killed
exit code 137 (KILL)
(Das local
Ding erfordert ash
/ pdksh
/ bash
/ zsh
, oder Sie können es ändern, typeset
was auch einige andere Muscheln verstehen.)
sleep 1 && echo $?
würde den Code der Schlafzelle nur drucken, wenn er Null ist ...