Come posso ottenere l'ID del processo genitore di un determinato processo figlio?


50

Come ottenere il pid genitore da un determinato pid figlio?

So di poterlo controllare manualmente in / proc, mi chiedo se ci sia un modo intelligente / migliore per farlo in Ubuntu. Nota che il genitore può o meno essere ucciso.

Grazie

Risposte:


58

Come ottenere un PID (PPID) principale dall'ID processo (PID) di un bambino utilizzando la riga di comando

Uso ps -o ppid=

  • es. ps -o ppid= 2072restituisce 2061, che può essere facilmente utilizzato in uno script, ecc. ps -o ppid= -C foofornisce il PPID del processo con comando foo. È inoltre possibile utilizzare il vecchio stile ps | grep: ps -eo ppid,comm | grep '[f]oo'.
  • Spiegazione più completa: ps -f 2072ritorna
    UID PID   PPID   C STIME TTY STAT TIME CMD
    izx 2072   2061   0 07:16? S 0:00 / usr / lib / pulseaudio / pulse / gconf-helper
    
  • La pstreerelazione è pstree -s -p 2072:
    init (1) ───pulseaudio (2061) ───gconf-helper (2072)
    

Conosci un modo per fare in modo che pstree mostri invocazioni (comando + argomenti) senza dividere le linee? La mia installazione divide automaticamente le linee se aggiungo argomenti, anche se il risultato potrebbe facilmente adattarsi a una riga. La pagina man sembra dire altrettanto, ma non fornisce un motivo. La mia soluzione alternativa prevede l'estrazione di PID da pstree e l'utilizzo ps -o args ...dei risultati, ma questo ha un po 'di odore.
John P

Solo qualcosa che mi ha sorpreso: lo spazio dopo ppid= ma prima del pid sembra essere necessario. Ho ottenuto risultati diversi se l'ho omesso.
Gregory Arenius

8

Utilizzando solo la variabile per ottenere il PID padre:

echo $PPID

se hai bisogno del comando da questo pid genitore:

cat /proc/$PPID/comm

se hai bisogno della riga di comando completa (con tutte le opzioni):

cat /proc/$PPID/cmdline

Spiegazione

  • $PPID è definito dalla shell, è il PID del processo genitore
  • in /proc/, hai alcune dir con il PID di ogni processo. Quindi, se si cat /proc/$PPID/comm, si fa eco al nome del comando del PID

Controlla man proc


1
Questa è la risposta migliore procfs è un'API del kernel. eseguire un comando e analizzare l'output è una sciocchezza.
Massimo

Questo è anche potenzialmente il più portatile, PPIDè definito come parte dello standard POSIX, quindi qualsiasi shell conforme a POSIX dovrebbe impostarlo in modo appropriato. Vedi pubs.opengroup.org/onlinepubs/9699919799/utilities/…
RobV

2

Usando pstreeper nome comando

Utilizzando pstreeè possibile cercare il nome del processo figlio e ottenere l'ID processo (PID) insieme ai genitori, ai nonni e a tutti i figli del processo figlio:

$ pstree -hp | grep sleep
           |-cron(763)---cron(795)---sh(839)---display-auto-br(841)---sleep(8414)

In questo caso sleepè il comando figlio ed è PID 8414. L'ID padre è 841 e viene chiamato display-auto-brightness. Il nonno è una shell ( sh) con un ID processo di 839. Il bisnonno ha cronun ID processo di 795. Il trisavolo ha anche cronun ID processo di 763.

Se si desidera cercare in base all'ID processo sleepanziché al nome, è possibile utilizzare:

$ pstree -hp | grep 14653
           |-cron(763)---cron(795)---sh(839)---display-auto-br(841)---sleep(14653)

Si noti che l' sleepID processo è cambiato in 14653. Il genitore (PID 841) dorme per 1 minuto, si sveglia per una frazione di secondo e quindi avvia un nuovo sleepcomando che ottiene un nuovo ID processo. Questo è un altro motivo per cui la ricerca sleepè più semplice della ricerca per ID processo.

Questo codice è stato preso da: Regola automaticamente la luminosità del display in base all'alba e al tramonto e adattato a questa domanda.


Per visualizzare una catena nidificata completamente indietro per avviare il processo, utilizzare il PID anziché il nome:

$ pstree -aps 8541
systemd,1 splash fastboot kaslr
  └─cron,763 -f
      └─cron,795 -f
          └─sh,839 -c    /usr/local/bin/display-auto-brightness
              └─display-auto-br,841 /usr/local/bin/display-auto-brightness
                  └─sleep,8541 60

Nota: è trascorso un altro minuto e il comando sleep ottiene un nuovo PID (8541).


Nel tuo esempio, questo metodo non avrebbe funzionato per il processo cron con PID 807.
Olorin

@Olorin In entrambi gli esempi potresti grep su 807o crone la stessa linea verrebbe ritrasformata così come più figli se generati. Ma la domanda era di trovare il genitore, non tutti i bambini.
WinEunuuchs2Unix

Esatto: come si trova il genitore del PID 807 con quell'output? Non puoi, perché non include il genitore di 807.
Olorin

@Olorin Il genitore di cron è systemd che è PID 1. Non credo che tu possa uccidere PID 1.
WinEunuuchs2Unix

Non ho detto nulla sull'uccisione di nulla. Giusto per chiarire, ora stai affermando che prendere la prima riga di pstree o grepping per il nome del comando darà sempre al PID genitore?
Olorin,

0

ps -efj può essere utilizzato anche per lo stesso.

Per esempio,

> ps -efj | head
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root         1     0     1     1  0 Jul01 ?        00:00:13 /sbin/init splash
root         2     0     0     0  0 Jul01 ?        00:00:00 [kthreadd]
root         3     2     0     0  0 Jul01 ?        00:00:02 [ksoftirqd/0]
root         5     2     0     0  0 Jul01 ?        00:00:00 [kworker/0:0H]
root         7     2     0     0  0 Jul01 ?        00:06:44 [rcu_sched]
root         8     2     0     0  0 Jul01 ?        00:00:00 [rcu_bh]
root         9     2     0     0  0 Jul01 ?        00:00:00 [migration/0]
root        10     2     0     0  0 Jul01 ?        00:00:08 [watchdog/0]
root        11     2     0     0  0 Jul01 ?        00:00:08 [watchdog/1]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.