Come intercettare il codice di uscita in script Bash
Domanda
Ci sono molti punti di uscita nel mio codice bash. Ho bisogno di fare un po 'pulita di lavoro fino all'uscita, così ho usato trappola per aggiungere una funzione di callback per l'uscita in questo modo:
trap "mycleanup" EXIT
Il problema è che ci sono diversi codici di uscita, ho bisogno di fare lavori di pulizia corrispondente. Posso ottenere il codice di uscita in mycleanup?
Soluzione
Penso che si possa utilizzare $?
per ottenere il codice di uscita.
Altri suggerimenti
La risposta accettata è fondamentalmente corretto, voglio solo chiarire le cose.
Il seguente esempio funziona bene:
#!/bin/bash
cleanup() {
rv=$?
rm -rf "$tmpdir"
exit $rv
}
tmpdir="$(mktemp)"
trap "cleanup" INT TERM EXIT
# Do things...
Ma bisogna essere più attenti se facendo pulizia in linea, senza funzione. Per esempio, questo non funzionerà:
trap "rv=$?; rm -rf $tmpdir; exit $rv" INT TERM EXIT
Invece si deve sfuggire alle variabili $rv
e $?
:
trap "rv=\$?; rm -rf $tmpdir; exit \$rv" INT TERM EXIT
Si potrebbe anche voler fuggire $tmpdir
, come si otterrà valutata quando viene eseguito la linea trappola e se il valore tmpdir
cambia in seguito che non si darà il comportamento previsto.
Modifica:. Usa shellcheck per verificare i propri script bash e di essere a conoscenza di problemi come questo
Ho trovato che è meglio per intrappolare uscita separata dalla trappola per altri segnali
Esempio script di test trappola ...
umask 77
tmpfile=`tmpfile.$$`
trap 'rm -f "$tmpfile"' EXIT
trap 'exit 2' HUP INT QUIT TERM
touch $tmpfile
read -r input
exit 10
Il file temporaneo viene ripulito. Il valore di uscita del file del 10 è conservata! Interrupt si traducono in un valore di uscita di 2
In pratica finché non si utilizza "uscita" in una trappola EXIT, si uscirà con il valore di uscita originali conservati.
PARTE: Nota l'citando nella trappola EXIT. Che mi permette di cambiare quello che le esigenze di file di essere ripulito per tutta la durata degli script. Ho spesso includono anche un test per l'esistenza del $ tmpfile prima di cercare di rimuoverlo, quindi non ho nemmeno bisogno di impostare all'inizio dello script, solo prima di crearlo.