Il server che gestisci ha appena smesso di rispondere. Un processo è andato in loop, la RAM è satura, e l'unico modo che conosci per uscirne è riavviare tutto. Lo abbiamo visto decine di volte: clienti che perdono ordini perché un job notturno è rimasto incastrato, sviluppatori che lanciano script interminabili e restano incollati al terminale per ore.
Noi, di Meteora Web, lavoriamo da anni su server Linux che devono reggere traffico reale, backup automatici e processi batch senza mai fermarsi. La gestione dei processi non è un lusso da sistemisti: è il pane quotidiano di chiunque tenga in piedi un sito o un'applicazione.
Questa guida ti porta dritto al punto: come vedere cosa sta succedendo (ps), come fermare con intelligenza (kill e segnali), come mandare in background e proteggere job dalla disconnessione (nohup, bg, fg, jobs). Niente teoria astratta: comandi che puoi copiare e testare subito.
Come usare ps per identificare processi in esecuzione e processi zombie?
Il primo passo per governare un server è sapere cosa sta girando. ps è lo strumento base, ma la maggior parte degli usi impropri produce output illeggibili. Vediamo i casi reali.
ps aux vs ps -ef: quale usare?
ps aux (senza trattino) è la versione BSD, ps -ef è POSIX. Entrambi mostrano tutti i processi di tutti gli utenti. Noi usiamo ps aux per leggibilità: colonne chiare con USER, PID, %CPU, %MEM, VSZ, RSS, STAT, START, TIME, COMMAND.
Sponsored Protocol
ps aux | head -10
La colonna STAT è fondamentale: R (running), S (sleeping), Z (zombie). Un processo zombie è un processo figlio terminato ma non ancora raccolto dal padre. Se ne vedi più di uno, il processo padre ha un baco. Identificalo con:
ps aux | grep 'Z'
Poi usa kill -SIGCHLD sul padre o, se non basta, uccidi il padre.
Filtrare per nome utente o comando
Se vuoi vedere solo i processi dell'utente www-data:
ps -U www-data u
Oppure cercare un processo specifico senza grep:
pgrep -a nginx # PID più comando
pkill -f "php.*artisan" # kill per pattern
Noi usiamo pgrep e pkill negli script di monitoraggio perché sono più puliti e evitano falsi positivi da grep stesso.
Processi figli e alberi gerarchici
Un processo può generare molti figli. Per vedere le relazioni:
ps auxf
Oppure l'albero completo:
pstree -p
Quando un processo padre muore senza raccogliere i figli, i figli diventano orfani e vengono adottati da init (PID 1). Se vedi un processo con PPID 1 che non dovrebbe star lì, qualcosa è andato storto.
Sponsored Protocol
Cosa fare adesso
- Apri un terminale e lancia
ps aux --sort=-%memper vedere i processi che consumano più RAM. - Controlla se ci sono zombie:
ps aux | grep -w Z - Salva l'output in un file per confronti futuri:
ps aux > /tmp/process_snapshot.txt
Quale segnale inviare con kill? SIGTERM vs SIGKILL e gestione pulita dei processi
kill non uccide: invia segnali. La differenza tra un processo che termina pulito e uno che lascia file temporanei o socket aperti sta nel segnale scelto.
I segnali che devi conoscere
| Segnale | Numero | Effetto |
|---|---|---|
| SIGTERM | 15 | Richiesta di terminazione gentile. Il processo può fare cleanup. |
| SIGKILL | 9 | Uccisione forzata immediata. Il processo non può ignorarlo. |
| SIGHUP | 1 | Ricarica configurazioni (molti daemon lo supportano). |
| SIGINT | 2 | Interrupt da tastiera (Ctrl+C). |
| SIGSTOP | 19 | Blocca il processo (non terminabile). |
| SIGCONT | 18 | Riprende un processo fermato. |
Procedura corretta per fermare un processo
- Prima prova SIGTERM:
kill -15 PID - Se dopo 5 secondi non risponde, SIGKILL:
kill -9 PID - Mai usare SIGKILL come prima opzione: rischi corruzione dati.
Negli script automatizzati, controlliamo sempre se il processo esiste prima di ucciderlo:
PID=$(pgrep -f "my-long-job")
if [ -n "$PID" ]; then
kill -15 $PID
sleep 5
if kill -0 $PID 2>/dev/null; then
kill -9 $PID
fi
fi
kill -0 non uccide, ma restituisce 0 se il processo esiste. Utile per test.
Sponsored Protocol
Killall e pkill: attenzione ai pattern
killall uccide per nome esatto, pkill per pattern. Noi preferiamo pkill -f con cautela: uccide anche processi il cui comando contiene la stringa. Per esempio pkill -f php potrebbe fermare tutti i PHP, non solo quelli voluti.
Cosa fare adesso
- Trova un processo in esecuzione (es.
sleep 9999 &) e testakill -15e poikill -9. - Esercitati con
kill -0per verificare se un processo è vivo. - Leggi
man 7 signalper l'elenco completo.
Come mandare in background un processo con nohup, bg, fg e jobs?
Hai uno script che deve girare per ore, ma non vuoi tenere il terminale aperto. Oppure hai lanciato un comando lungo e ti sei dimenticato di metterlo in background. Vediamo le soluzioni.
Eseguire un processo in background direttamente
./mia_elaborazione.sh &
Lo shell restituisce subito il controllo. Il processo gira in background, ma se chiudi il terminale riceve SIGHUP e muore. Per evitarlo:
nohup ./mia_elaborazione.sh &
nohup ignora SIGHUP e redirige l'output su nohup.out se non specificato diversamente.
Sponsored Protocol
Portare un processo in background dopo averlo lanciato
Hai lanciato ./lungo_job e ora sei bloccato? Premi Ctrl+Z per sospenderlo, poi:
bg # lo fa ripartire in background
Per riportarlo in primo piano:
fg %1
Il numero dopo % è l'ID del job (lo vedi con jobs).
Jobs: gestire background job multipli
jobs -l # mostra anche i PID
[1]+ Running nohup ./script1.sh &
[2]- Stopped ./script2.sh
Il + indica il job corrente (quello su cui agiscono fg e bg). Puoi fare fg %2 per portare in primo piano il secondo.
Disown: staccare un job dal terminale
Se un job è già in background e vuoi che sopravviva alla chiusura del terminale, usa disown:
./lungo_job &
disown %1
Da quel momento il processo è orfano e non riceve più SIGHUP. Alternativa: nohup al lancio.
Alternative robuste: screen e tmux
nohup e disown sono leggeri, ma se devi riconnetterti a un processo interattivo (es. editor, debugger), servono multiplexer:
screen -S miojob
./lungo_job
# stacca con Ctrl+A D
# riconnetti: screen -r miojob
Noi usiamo tmux sui server di produzione perché permette sessioni multiple e persistenza anche dopo crash della shell.
Sponsored Protocol
Cosa fare adesso
- Lancia
sleep 300 &poijobsedisown %1. Chiudi il terminale, riaprilo e verifica che il processo sia ancora in esecuzione conps aux | grep sleep. - Installa screen o tmux (
apt install tmux) e crea una sessione persistente. - Se sei sviluppatore, usa
nohupper gli script di deploy lunghi: eviti di lasciare il terminale aperto.
Cosa fare adesso — In sintesi
- Impara a leggere ps:
ps aux --sort=-%cpuè il tuo cruscotto quotidiano. - Usa i segnali giusti: SIGTERM prima, SIGKILL solo come extrema ratio.
- Background job senza pensieri:
nohup comando &odisownper processi che devono sopravvivere. - Esplora tmux/screen: quando un processo interattivo deve restare acceso, non c'è alternativa.
- Automatizza il monitoraggio: scrivi uno script che ogni ora salva
ps auxe controlla la presenza di zombie (noi lo facciamo con cron e un alert via Telegram).
La gestione dei processi è la differenza tra un server che si spegne e uno che regge anni senza reboot. Noi, di Meteora Web, abbiamo dedicato un'intera guida alla shell scripting e automazione Linux, di cui questo approfondimento fa parte. Se il tuo server ha ancora processi zombie in giro, hai già il primo passo da fare.