Corso Linux / Come controllare, sospendere e terminare i processi

Per gestire i processi Linux, identifica il programma in esecuzione, osservane stato e consumo di risorse e invia un segnale soltanto quando serve intervenire. ps fornisce un’istantanea, mentre top aggiorna la visualizzazione. Per terminare un processo, richiedi prima la chiusura con TERM; riserva il segnale non intercettabile KILL ai casi in cui i tentativi meno drastici non hanno funzionato.

Questa lezione introduce stati, controllo dei job e segnali. Il corso su PID e PPID approfondisce il cambio del processo padre, gli zombie e i namespace dei PID. Gli esempi di consultazione seguenti presuppongono Linux con gli strumenti procps-ng: il comando ps di Git Bash su Windows non supporta le stesse opzioni.

Distinguere processi e job della shell

Un processo è un’istanza di un programma in esecuzione ed è identificato da un PID (Process ID, identificatore del processo). Il PPID (Parent Process ID) identifica il suo padre attuale, che può cambiare se il padre precedente termina. I numeri vanno interpretati nel namespace dei PID in cui vengono osservati. Un job è invece un’unità di esecuzione gestita da una specifica shell e può comprendere più processi. Un identificatore come %1 appartiene al controllo dei job di quella shell e non è un PID.

Alcuni processi appartengono a servizi, ma non tutti i processi sono servizi. Prima di terminare il singolo processo di un servizio, controlla stato e log tramite il gestore dei servizi: potrebbe riavviarlo automaticamente o coordinare più processi. Qui ci concentriamo sull’osservazione e sul controllo di un processo di prova avviato dal tuo account.

Scegliere le colonne utili con ps

ps mostra i processi al momento dell’esecuzione. Per osservare il sistema, specificare le colonne permette di confrontare PID, padre, utente, stato, tempo trascorso e comando. L’elenco può essere lungo: restringi la selezione a un PID o programma noto quando possibile. La visibilità può essere limitata da permessi, configurazione di /proc e namespace.

ps -eo pid,ppid,user,stat,etime,args
ps -eo pid,ppid,user,%cpu,%mem,stat,args --sort=-%cpu | head

La prima riga include ETIME, il tempo trascorso dall’avvio, non il tempo di utilizzo del processore. USER indica l’utente effettivo. Il secondo comando ordina per utilizzo della CPU (unità centrale di elaborazione) in ordine decrescente e mostra le prime righe. In procps-ng, %CPU di ps è il rapporto fra tempo CPU consumato e tempo trascorso dall’avvio: non è necessariamente una misura dell’ultimo istante come una lettura periodica. Una singola schermata non dimostra la causa di un rallentamento.

Il primo carattere di STAT descrive lo stato principale: R significa in esecuzione o pronto a eseguire; S, attesa interrompibile; D, attesa non interrompibile, spesso legata all’input/output; T, processo sospeso da un segnale di controllo; Z, processo figlio già terminato il cui stato non è ancora stato raccolto dal padre, detto zombie. I caratteri successivi possono indicare altre proprietà.

Osservare i cambiamenti con top e cercare con pgrep

top aggiorna periodicamente processi e consumo di risorse. Ordinamento e valori mostrati dipendono dalla configurazione. Premi q per uscire. È utile per seguire l’andamento nel tempo senza eseguire ripetutamente ps.

top

pgrep cerca i PID in base al nome; -a aggiunge la riga di comando ai risultati. Questa opzione cambia ciò che viene mostrato, non trasforma la ricerca in una ricerca nell’intera riga di comando: per quest’ultima esiste -f. Il criterio è un’espressione regolare, quindi possono comparire più processi con nomi simili. Un processo può terminare subito dopo la ricerca e il suo PID può essere riutilizzato: non interrompere un programma soltanto perché un numero è apparso nell’elenco.

pgrep -a sleep

Se non compare nulla, potrebbe non esserci una corrispondenza, la visibilità potrebbe essere limitata o il criterio potrebbe non essere adatto. Per osservare il proprio processo di prova è più preciso usare il PID registrato dalla shell nell’esercizio seguente.

Sospendere e riprendere un proprio processo

Esegui i comandi uno alla volta in una sessione interattiva di Bash su Linux, controllando ciascun risultato. sleep 300 & avvia in background un processo che attende 300 secondi; $! restituisce il PID del job avviato più recentemente in background. In questo esempio il job contiene il solo sleep. Usa una nuova variabile practice_pid e resta nella stessa shell fino alla fine, senza avviare altri job fra le prime due righe. Non fare questa prova su processi di altri utenti o su servizi di produzione.

sleep 300 &
practice_pid=$!
printf 'practice PID: %s\n' "$practice_pid"
ps -p "$practice_pid" -o pid,ppid,stat,etime,args
kill -STOP "$practice_pid"
ps -p "$practice_pid" -o pid,stat,args
kill -CONT "$practice_pid"
ps -p "$practice_pid" -o pid,stat,args

Il primo ps deve identificare proprio il tuo sleep. Se il PID è vuoto, il comando fallisce o il processo non è quello atteso, fermati e ricomincia con un nuovo processo di prova. Dopo STOP lo stato normalmente inizia con T; dopo CONT può tornare a S o a un altro stato. L’osservazione dipende dal momento: se necessario ripeti la sola interrogazione ps sul processo appena avviato. STOP sospende l’esecuzione senza terminarla; CONT la riprende. Come KILL, STOP non può essere intercettato, bloccato o ignorato dal processo.

Richiedere la chiusura con TERM e verificarla

Concludi la prova nella stessa shell, dopo aver ripreso il processo con CONT. TERM è il segnale di terminazione predefinito di kill. Un programma può gestirlo per eseguire operazioni di chiusura, ma queste non sono garantite: il comportamento predefinito è terminare, e un programma può anche ignorare il segnale. wait attende questo figlio e ne raccoglie lo stato. Poiché il processo termina per un segnale, il risultato di wait può essere diverso da zero; nella prova interattiva passa poi al controllo con ps.

kill -TERM "$practice_pid"
wait "$practice_pid"
ps -p "$practice_pid" -o pid,stat,args

Se l’ultimo ps mostra soltanto l’intestazione o termina indicando che non ci sono corrispondenze, normalmente il processo di prova è scomparso. Un PID può essere riutilizzato: ritrovare quel numero molto più tardi non dimostra che sia lo stesso processo. Se un altro programma gestisce o ignora TERM, concedigli tempo e controlla stato e log; non ripetere alla cieca segnali verso un vecchio PID. wait riguarda figli della shell corrente, non processi arbitrari appartenenti ad altri terminali.

kill -KILL PID non offre al processo la possibilità di gestire il segnale o svolgere le proprie operazioni di chiusura. Può lasciare incompleta una scrittura o compromettere la coerenza di un database o servizio. Valutalo soltanto quando identità e conseguenze sono chiare e la terminazione ordinaria non è riuscita. L’invio dei segnali richiede autorizzazione: normalmente un utente non privilegiato agisce sui propri processi; le regole dipendono dagli identificatori utente e, per CONT, esiste anche una condizione relativa alla stessa sessione. Un processo in stato D può non scomparire immediatamente nemmeno dopo un segnale forzato, finché l’attesa nel kernel non si risolve.

Job in primo piano e in background

In Bash, comando & avvia un job in background. jobs -l elenca numeri dei job e PID seguiti dalla shell corrente: non è l’elenco di tutti i processi del computer né dei job di un altro terminale. Se sospendi un job in primo piano con Ctrl+Z, puoi riprenderlo in background con bg %1 oppure riportarlo in primo piano con fg %1. Scegli il numero reale da jobs: non presumere che sia sempre 1. Queste operazioni richiedono il controllo dei job, normalmente attivo in Bash interattivo con un terminale.

jobs -l

Avviare un programma in background non lo trasforma in un servizio affidabile che sopravvive al logout. Sessione, input/output e segnali possono ancora influenzarlo. Per un processo server da gestire continuamente usa il meccanismo di gestione dei servizi previsto dalla distribuzione.

Come diagnosticare un processo problematico

  1. Usa ps o pgrep per confermare PID, comando, utente e padre. Non dedurre l’identità da un nome simile.
  2. Con top e i log pertinenti valuta se il consumo di CPU o memoria persiste, se il processo è soltanto in attesa o se esiste un errore.
  3. Verifica se appartiene a un servizio. In quel caso consulta prima lo stato e i log tramite il gestore del servizio.
  4. Se un tuo processo deve terminare, richiedi la chiusura con TERM e lascia il tempo necessario. Scegli altre azioni soltanto quando servono.
  5. Controlla di nuovo con ps e indaga eventuali riavvii automatici, ricorrenze e cause del problema.

Documentazione di riferimento

Il manuale ps(1) definisce campi e codici di stato. Il manuale pgrep(1) spiega i criteri di ricerca e quello di top(1) i comandi interattivi. Consulta signal(7) per l’effetto dei segnali e kill(2) per le condizioni di autorizzazione. Il manuale GNU Bash distribuito da Debian descrive kill, wait, i numeri dei job, fg e bg.