Propagare il codice di uscita per chiamare in caso di un errore della shell dallo script avente una trappola di uscita
Domanda
È possibile propagare un codice di uscita al chiamante in caso di un errore di sintassi in uno script bash con una trappola di uscita?Ad esempio, se ho:
#! /bin/bash
set -eu
trap "echo dying!!" EXIT
echo yeah
echo $UNBOUND_VARIABLE
echo boo
.
Quindi, eseguirlo dà un codice di uscita 0 anche se lo script non ha davvero finito con successo:
$ bash test.sh
yeah
test.sh: line 8: UNBOUND_VARIABLE: unbound variable
dying!!
$ echo $?
0
.
Ma se commendo la trappola di uscita, lo script ritorna 1. In alternativa, se sostituisco la linea con la variabile non legata con un comando che restituisce non zero (ad es. /bin/false
), quel valore di uscita è propagato come vorrei.
Soluzione 2
Questo comportamento è correlato a diverse versioni di bash.Lo script originale funziona come previsto su Bash 4.2 ma non su 3.2.Avere il codice soggetto all'errore in un file di script separato e eseguirlo in un subshell funziona attorno ai problemi nelle versioni in precedenti Bash:
#!/bin/bash
$BASH sub.sh
RETVAL=$?
if [[ "$RETVAL" != "0" ]]; then
echo "Dying!! Exit code: $RETVAL"
fi
.
sub.sh:
set -eu
echo yeah
echo $UNBOUND_VARIABLE
echo boo
. Altri suggerimenti
La shell esce dal risultato dell'ultimo comando eseguito.Nel tuo caso di trappola, questo è echo
, che di solito restituisce con successo.
Per propagare il tuo valore, semplicemente exit
con esso.
#!/bin/bash
set -eu
die() {
echo "Dying!!"
exit "$1"
}
trap 'die $?' EXIT
echo yeah
echo $unbound
echo boo
.
Si noti inoltre che set -e
è considerato dannoso - ti fa pensare che lo script uscirà se un comando fallisce, che non lo farà sempre.