Si chiamano comunemente codici di uscita (in inglese exit codes o exit status). Sono un concetto fondamentale nei sistemi operativi Unix-like (Linux, macOS, BSD, ecc.) e vengono utilizzati per comunicare l’esito dell’esecuzione di un programma o comando.
Un codice di uscita è un valore intero che un processo restituisce al proprio processo padre (tipicamente la shell da cui è stato lanciato) nel momento in cui la sua esecuzione termina. Questo valore fornisce informazioni sull’esito dell’esecuzione; quindi se il comando è stato completato con successo oppure ha generato un errore.
Principio fondamentale:
0(zero): indica il successo. Il programma si è concluso correttamente e senza errori.- Qualsiasi valore diverso da
0: segnala un errore o un fallimento. Il significato preciso può variare a seconda del programma.
I codici di uscita sono fondamentali per la scrittura di script shell e per l’automazione, in quanto consentono di verificare il risultato dei comandi e prendere decisioni di conseguenza.
Verifica del codice di uscita ($?)
In Bash (e shell simili), il codice di uscita dell’ultimo comando eseguito è memorizzato nella variabile speciale $?. Per esempio:
ls /tmp/file_esistente.txt
echo $? # Output: 0
ls /tmp/file_non_esistente.txt
echo $? # Output: 2 (file o directory non trovati)
Bash – Usare gli operatori di controllo (&& e ||) per direzionare le esecuzioni di più comandi
&& e ||:
questi due operatori logici condizionali sfruttano i codici di uscita per decidere se eseguire il comando successivo. Quindi:
comando1 && comando2: eseguecomando2solo secomando1termina con successo (cioè con codice 0).mkdir mia_dir && cd mia_dir && echo "Directory creata e navigata."comando1 || comando2: eseguecomando2solo secomando1termina con un errore (cioè con codice diverso da 0).grep "parola" file_inesistente.txt || echo "File inesistente o parola non trovata."
Script Bash – sfruttare l’exit code per rendere più dinamico l’output
Negli script, è comune sfruttare il codice di uscita salvandolo in una variabile e usarlo per fornire un output dinamico sullo stato dell’esecuzione:
#!/bin/bash
cp /file_sorgente.txt /cartella_destinazione/
EXIT_STATUS=$?
if [ $EXIT_STATUS -eq 0 ]; then
echo "Copia completata con successo."
else
echo "Errore durante la copia. Codice di uscita: $EXIT_STATUS"
fi
Codici di uscita comuni e convenzioni
Sebbene ogni programma possa definire i propri codici di uscita, esistono alcune convenzioni comuni:
| Codice | Significato |
|---|---|
0 | Successo. |
1 | Errore generico (catch-all). |
2 | Errore di uso del comando (es. argomenti errati). |
126 | Comando trovato ma non eseguibile (permessi insufficienti). |
127 | Comando non trovato. |
128 + N | Terminazione causata da un segnale POSIX. N è il numero del segnale ricevuto. |
Esempi di codici 128 + N:
130= 128 + 2 → interruzione conCtrl+C(SIGINT)137= 128 + 9 → terminazione forzata conkill -9(SIGKILL)
Altri codici (da 1 a 255) possono essere definiti dai singoli programmi per indicare errori specifici. Ad esempio, un programma di backup potrebbe restituire:
10→ file mancante,11→ spazio su disco insufficiente.
È buona pratica documentare chiaramente questi codici nei manuali o nella documentazione del programma.
Limiti dei codici di uscita
I codici di uscita sono interi senza segno e, nei sistemi POSIX, sono limitati all’intervallo 0–255. Se un programma tenta di terminare con un valore superiore (es. exit 300), verrà restituito solo il valore modulo 256. Esempio:
exit 257 # Risultato effettivo: 1 (perché 257 % 256 = 1)
Gestione dei codici di uscita in Python
Anche in Python, il comportamento dei codici di uscita segue la stessa logica di Unix e del linguaggio C. Quando uno script Python viene eseguito, il processo associato termina restituendo un exit status al sistema operativo, che può essere interpretato da altre applicazioni o script.
Comportamento predefinito degli exit code in Python
- Se lo script Python termina normalmente, senza eccezioni non gestite e senza una chiamata esplicita a
sys.exit(), il codice di uscita restituito sarà0, che indica successo. - Se durante l’esecuzione si verifica un’eccezione non gestita, Python stampa lo stack trace e il processo termina con un codice di uscita diverso da 0 (tipicamente
1,). - Se si chiama
sys.exit(N), il programma termina immediatamente con il codiceN, che può essere qualsiasi intero da0a255.
“Dichiarare l’exit code” tramite l’uso esplicito con sys.exit()
Per controllare in modo esplicito il codice di uscita in uno script Python, si utilizza la funzione sys.exit(), definita nel modulo sys. Può essere utile per segnalare errori specifici o per interrompere volontariamente il flusso in base a una condizione.
import sys
if not some_condition:
print("Errore: condizione non soddisfatta.")
sys.exit(2) # Codice di errore personalizzato
print("Tutto OK.")
sys.exit(0) # Termine esplicito con successo
Esempi pratici
✅ successo.py — terminazione corretta
print("Questo script è terminato con successo.")
# Nessuna chiamata a sys.exit() → il codice di uscita sarà 0
❌ errore.py — errore esplicito
import sys
print("Errore esplicito generato.")
sys.exit(1) # Termine forzato con errore
⚠️ errore_eccezione.py — eccezione non gestita
print("Questo script genererà un'eccezione.")
x = 1 / 0 # Divisione per zero → eccezione non gestita → codice di uscita ≠ 0
Verifica in una shell Unix/Linux
Se testiamo i tra file Python sopra riportati in una shell con il comando $…
python successo.py
echo $? # Output: 0
python errore.py
echo $? # Output: 1
python errore_eccezione.py
echo $? # Output: 1
Quindi anche qui potrò sfruttare gli operatori condizionali per rendere le esecuzioni dei miei script più “dinamiche”:
python successo.py && echo "Script completato con successo."
# Output: stampa entrambi i messaggi
python errore.py && echo "Questo messaggio NON verrà stampato."
# Output: solo il messaggio dello script, non quello dopo "&&"
