Corso Linux / PID e PPID: identificare processi e rapporti padre-figlio
Il PID (process ID) identifica un processo in esecuzione; il PPID (parent process ID) è il PID del suo genitore attuale, che può cambiare se il processo viene riassegnato a un altro genitore. Su Linux questi numeri permettono di individuare un processo, leggere i rapporti padre-figlio e, quando necessario, indirizzare un segnale. Il kernel assegna gli identificatori: ciò che gestisci sono i processi attualmente associati a quei numeri.
Qual è la differenza tra PID e PPID?
Un processo è un’istanza di un programma in esecuzione. Avviare due volte lo stesso programma crea normalmente due processi con PID diversi. Quando un processo ne crea un altro, il nuovo processo ha un PPID che identifica il genitore.
| Campo | Significato | Utilizzo |
|---|---|---|
| PID | Identificatore del processo | Selezionare un processo per interrogarlo o inviargli un segnale |
| PPID | PID del genitore attuale | Esaminare il rapporto padre-figlio, tenendo conto di eventuali riassegnazioni |
Se una shell ha PID 4250 e avvia un sleep con PID 4321, il PPID di sleep può essere 4250. Sono numeri illustrativi. Un PID non è permanente: dopo la conclusione di un processo può essere riutilizzato. Inoltre, con i namespace dei PID, come nei container, lo stesso processo può apparire con numeri diversi secondo il punto di osservazione.
Come controllare PID e PPID di un processo
Usa ps specificando le colonne necessarie. Gli esempi di selezione e formato presuppongono il ps di procps-ng su Linux e una shell Bash: implementazioni minime o di altri sistemi possono avere opzioni differenti. In una sessione Bash interattiva, $$ identifica la shell; il comando seguente ne legge le informazioni.
ps -p "$$" -o pid,ppid,user,stat,etime,args
Le colonne dipendono dal formato richiesto: PID è l’identificatore della shell, PPID quello del genitore, USER indica l’utente effettivo, STAT lo stato e gli eventuali indicatori aggiuntivi, ELAPSED il tempo trascorso dall’avvio e COMMAND o ARGS la riga di comando. Ecco un output illustrativo:
PID PPID USER STAT ELAPSED COMMAND
4250 4110 learner Ss 00:42 -bash
Non aspettarti quei numeri o quel nome utente sul tuo sistema. Per leggere un PID noto puoi usare ps -p 4321 -o pid,ppid,args, sostituendo il numero con quello realmente individuato. Se il vecchio processo è terminato, la riga può mancare; se il numero è già stato riutilizzato, può descrivere un altro processo. Per elencare i processi attualmente visibili usa ps -eo pid,ppid,user,stat,args e, per una lista lunga, collegalo a less.
Per cercare per nome usa pgrep -a -x sleep: -x richiede la corrispondenza esatta del nome del processo e -a mostra anche la riga di comando. Più processi possono condividere il nome e nessuna corrispondenza non prova da sola un errore del sistema: il processo potrebbe non essere visibile o essere già terminato. Non identificare il tuo lavoro soltanto dal primo numero stampato. Le guide di ps e pgrep approfondiscono le opzioni.
Leggere i rapporti padre-figlio senza modificare i processi
La lezione sulla gestione di processi e lavori (in inglese) contiene l’esercizio di creazione e invio di segnali. Qui leggi soltanto la shell e i suoi figli diretti. Il comando ps usato per la lettura può comparire esso stesso come figlio temporaneo; altri processi possono terminare tra due interrogazioni.
ps -p "$$" -o pid,ppid,user,lstart,args
ps --ppid "$$" -o pid,ppid,stat,args
La prima riga include lstart, la data e ora di avvio, utile da confrontare con nome e utente. La seconda seleziona i processi il cui PPID coincide con il PID della shell: non elenca automaticamente tutti i discendenti dei figli. Una lista vuota può semplicemente indicare che al momento della lettura non c’erano figli corrispondenti visibili.
In una sottoshell Bash creata con parentesi tonde, $$ conserva il valore della Bash esterna; $BASHPID indica invece il processo Bash corrente. Non assegnare valori a queste variabili per le prove. Se pstree è installato, pstree -p "$$" offre una vista ad albero con identificatori; anche questa rappresenta una situazione che può cambiare subito dopo.
Distinguere namespace dei PID e riutilizzo dei numeri
Un namespace dei PID è un ambito separato di identificatori dei processi. Lo stesso processo può avere numeri diversi dal punto di vista dell’host e del container; i processi visibili dipendono anche dalla gerarchia dei namespace. Questi comandi leggono il collegamento al namespace della shell e il campo NSpid del suo stato nel filesystem proc visibile:
readlink "/proc/$$/ns/pid"
grep '^NSpid:' "/proc/$$/status"
readlink può mostrare un identificatore nella forma pid:[numero]: quel numero identifica il namespace e non è il PID della shell. Il campo NSpid elenca gli identificatori nelle gerarchie visibili a partire dal namespace che ha montato quel proc. In un ambiente semplice può esserci un solo valore; kernel, montaggio di proc e permessi possono limitare l’accesso o l’esistenza dei campi. L’assenza di una riga non è una dimostrazione che i namespace non esistano.
La differenza tra namespace riguarda il punto di osservazione; il riutilizzo avviene quando un processo successivo riceve il numero di uno già terminato. Non confondere i fenomeni e non mescolare PID dell’host e del container quando scegli un destinatario per un segnale.
Che cosa succede quando termina il genitore?
Terminare un genitore non termina necessariamente tutti i figli. Un figlio ancora vivo può essere riassegnato a un altro processo e cambiare PPID. Perciò il PPID descrive il genitore attuale, non sempre il creatore storico, e inviare un segnale al solo genitore non garantisce la pulizia di tutto l’albero.
Un figlio che ha terminato l’esecuzione, ma di cui il genitore non ha ancora raccolto lo stato, può rimanere come processo zombie. Non sta più eseguendo il programma: inviare ripetutamente KILL a quel numero non risolve la mancata raccolta. Va esaminato il comportamento del genitore che deve raccogliere lo stato. Il comando incorporato Bash wait permette di attendere e ottenere lo stato dei figli di quella shell; non è un’attesa generica su qualunque PID del sistema.
Un PID è un identificatore valido in un determinato momento e ambito. Non scegliere un processo da terminare usando soltanto un vecchio file PID o un numero annotato. Controlla comando, utente e avvio; verifica anche il namespace. Questi controlli riducono gli equivoci, ma un processo può comunque terminare tra lettura e azione: per i servizi gestiti usa l’interfaccia del loro gestore.
Come gestire un processo di servizio
Un servizio gestito da systemd può cambiare PID dopo un riavvio. In questo caso esamina l’unità di servizio invece di inviare direttamente segnali a un numero. Se nginx.service è realmente installato, systemctl status nginx.service ne mostra lo stato. Solo quando un riavvio è previsto e autorizzato per l’attività operativa, sudo systemctl restart nginx.service lo arresta e lo avvia; può avviarlo anche se era fermo e può interrompere le richieste in corso. È una possibilità da valutare, non un comando da eseguire in questa esercitazione di lettura.
Se nginx non è installato o viene usato un altro gestore, verifica prima nome del servizio e metodo appropriato. PID e PPID aiutano a identificare processo e rapporto di parentela; per fermare un lavoro restringi il destinatario esatto e, se è un servizio gestito, usa il gestore del servizio.
Documentazione di riferimento
I manuali di ps di procps-ng e pgrep di procps-ng descrivono selezioni e colonne. Le pagine Linux sui namespace dei PID e sullo stato di un processo in proc spiegano visibilità e campo NSpid.
Il manuale ufficiale di Bash distribuito da Debian documenta $$, BASHPID e wait. Per raccolta dei figli e zombie consulta wait(2); per stato e riavvio delle unità consulta il manuale ufficiale di systemctl.




