Sto osservando un comportamento strano quando si usa set -e
( errexit
), set -u
( nounset
) insieme alle trappole ERR ed EXIT. Sembrano collegati, quindi metterli in una domanda sembra ragionevole.
1) set -u
non attiva trappole ERR
Codice:
#!/bin/bash trap 'echo "ERR (rc: $?)"' ERR set -u echo ${UNSET_VAR}
- Previsto: viene chiamata la trap ERR, RC! = 0
- Effettivo: la trap ERR non viene chiamata, RC == 1
- Nota:
set -e
non cambia il risultato
2) L'uso set -eu
del codice di uscita in una trap EXIT è 0 invece di 1
Codice:
#!/bin/bash trap 'echo "EXIT (rc: $?)"' EXIT set -eu echo ${UNSET_VAR}
- Previsto: viene chiamata la trap EXIT, RC == 1
- Effettivo: viene chiamata la trap EXIT, RC == 0
- Nota: quando si utilizza
set +e
, RC == 1. La trap EXIT restituisce il RC corretto quando qualsiasi altro comando genera un errore. - Modifica: C'è un post SO su questo argomento con un commento interessante che suggerisce che questo potrebbe essere correlato alla versione di Bash in uso. Testare questo frammento con Bash 4.3.11 produce un RC = 1, quindi è meglio. Sfortunatamente al momento non è possibile aggiornare Bash (dalla 3.2.51) su tutti gli host, quindi dobbiamo trovare un'altra soluzione.
Qualcuno può spiegare uno di questi comportamenti?
La ricerca di questi argomenti non ha avuto molto successo, il che è piuttosto sorprendente dato il numero di post su impostazioni e trappole di Bash. C'è un thread del forum , però, ma la conclusione è piuttosto insoddisfacente.
set -e
e set -u
sono entrambi progettati specificamente per uccidere un guscio con script. Usarli in condizioni che potrebbero innescare la loro applicazione ucciderà una shell con script. Non c'è modo di aggirarlo, tranne per non usarli, e invece per testare quelle condizioni quando si applicano in una sequenza di codice. Quindi, in sostanza, puoi scrivere un buon codice shell o puoi usarlo set -eu
.
-u
non attivare la trap ERR (è un errore, quindi non dovrebbe attivare la trap) o il codice di errore è 0 invece di 1. Il quest'ultimo sembra essere un bug che è già stato corretto nella versione successiva, quindi è quello. Ma la prima parte è piuttosto difficile da capire se non ti sei reso conto che gli errori nella valutazione della shell (espansione dei parametri) e gli errori reali nei comandi sembrano essere due cose diverse. Per la soluzione, bene, come hai suggerito, ora sto cercando di evitare -eu
e controllare manualmente quando è necessario.
(set -u; : $UNSET_VAR)
e simili. Anche questo tipo di cose può essere buono - puoi lasciarne cadere molte di &&
tanto in tanto: (set -e; mkdir dir; cd dir; touch dirfile)
se ottieni la mia deriva. È solo che si tratta di contesti controllati: quando li imposti come opzioni globali, perdi il controllo e diventi controllato. Di solito ci sono soluzioni più efficienti.
bash
rotto con lo standard e ho iniziato a mettere trappole nelle sottosche. La trappola dovrebbe essere eseguita nello stesso ambiente da cui proviene il ritorno, mabash
non lo fa da un po 'di tempo.