- 2026-09-03
- 2 minuti
Bash Error Handling #2: trap e cleanup per script affidabili

Nel primo episodio abbiamo messo la cintura di sicurezza (set -euo pipefail).
Ottimo inizio.
Ora passiamo al problema successivo: gli script che, quando falliscono, lasciano dietro di sé una vera scena del crimine in cartelle come /tmp.
Perché trap salva vite (digitali)
Scenario classico:
- crei una directory temporanea
- fai operazioni intermedie
- qualcosa va storto
- lo script termina
- la directory resta lì per sempre, insieme ad altri 200 reperti archeologici
Con trap puoi eseguire cleanup sempre, sia in caso di successo che di errore.
Vediamo come si usa: aggiungiamo in cima allo script la notazione shebang che, ricordiamo, indica al sistema operativo quale interprete usare per eseguire il file. Poi, inseriamo l’istruzione set -euo pipefail per abilitare le opzioni di sicurezza che abbiamo discusso nel primo episodio. Successivamente, creiamo una directory temporanea con mktemp e impostiamo un trap per rimuoverla quando lo script termina, indipendentemente dal motivo della terminazione.
#!/usr/bin/env bash
set -euo pipefail
TMP_DIR=$(mktemp -d)
trap 'rm -rf "$TMP_DIR"' EXIT
echo "Uso temp dir: $TMP_DIR"
# comandi vari...
EXIT scatta quando lo script termina per qualsiasi motivo: bene, male, o panico da tastiera.
Anche Ctrl+C non ti sorprende più
Se l’utente interrompe con Ctrl+C (SIGINT), puoi intercettarlo per loggare meglio o fare cleanup custom in questo modo: usando una funzione dedicata e un trap specifico per il segnale INT, che rappresenta l’interruzione da tastiera. In questo esempio, la funzione on_interrupt stampa un messaggio e termina lo script con un codice di uscita specifico (130), che indica che l’interruzione è stata causata dall’utente.
#!/usr/bin/env bash
set -euo pipefail
TMP_DIR=$(mktemp -d)
cleanup() {
rm -rf "$TMP_DIR"
}
on_interrupt() {
echo "Interrotto dall'utente, chiudo in modo pulito" >&2
exit 130
}
trap cleanup EXIT
trap on_interrupt INT
Ora almeno il tuo script non sparisce in una nuvola di ambiguità!
Non tutti i codici di errore sono catastrofi
Con set -e, alcuni comandi che ritornano 1 possono far fallire script che in realtà stanno facendo cose lecite.
Esempio tipico: controllo stato servizio. Nell’esempio seguente, se il servizio non è attivo, lo script non fallisce: semplicemente lo avvia. Se invece il servizio è già attivo, lo riavvia. Questo approccio consente di gestire i fallimenti attesi senza interrompere l’esecuzione dello script.
if systemctl is-active --quiet myservice; then
systemctl restart myservice
else
systemctl start myservice
fi
Qui un “non attivo” non è un disastro: è solo un’informazione che descrive lo stato del servizio. In questo caso, gestiamo il fallimento atteso con un semplice if, evitando che lo script si interrompa inutilmente.
Regola pratica:
- fallimenti attesi -> gestiscili con
if - fallimenti inattesi -> lascia che
set -einterrompa tutto
Pattern riusabile
Questo scheletro di script è un buon punto di partenza per i tuoi script Bash, garantendo che le risorse temporanee vengano sempre pulite e che l’utente riceva un feedback chiaro in caso di interruzione.
#!/usr/bin/env bash
set -euo pipefail
TMP_DIR=$(mktemp -d)
cleanup() { rm -rf "$TMP_DIR"; }
trap cleanup EXIT
main() {
echo "Faccio cose pericolose ma con una buona dose di responsabilità"
}
main "$@"
Semplice, leggibile, e riduce una classe intera di problemi operativi.
In sintesi
trap è il tuo “ci penso io” finale. Senza, avremmo script veloci, sporchi, e sicuramente memorabili (nel modo sbagliato).
Nel terzo e ultimo episodio chiudiamo con logging, validazione input e test, per capire come passare da “script che spera” a “script che regge”.
















