Bash Error Handling #2: trap e cleanup per script affidabili

Immagine di copertina

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 -e interrompa 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”.

Conosci meglio chi ha scritto questo articolo

Serena Sensini

Ciao! Mi chiamo Serena Sensini e sono la creatrice di @ TheRedCode.it. Ho aperto questo blog nel 2021 per raccontare il mio lavoro e il mondo dell’informatica a parole semplici, in piccole pillole e alla portata di tutte le persone.

Sono un’ingegnera informatica specializzata in ambito AI & NLP. Di giorno lavoro come CTO @ Welyk e come Innovation & Emerging Technologies Leader @ Dedalus, mentre di notte scrivo e sono autrice di 5 libri -per ora-. 🖊️

Foto di Serena Sensini

Partners

Community, aziende e persone che supportano attivamente il blog

Vuoi diventare partner?

Collaboriamo con community, aziende e strumenti del mondo tech che vogliono raggiungere la nostra community di dev ed engineer italiani. Scrivici per proporre una collaborazione.

Vuoi diventare tech content creator? 🖊️

Se ti va di raccontare la tua esperienza nel mondo tech, questo è il posto giusto.

Cerchiamo voci autentiche, esempi pratici e punti di vista utili per chi legge.

Scrivici a collaborazioni[at]theredcode.it con una proposta: idea, taglio del contenuto e una breve presentazione. Non vediamo l'ora di leggere la tua esperienza!

Invia la tua idea