Як отримати ідентифікатор батьківського процесу для даного дочірнього процесу?


49

Як отримати батьківський під від даного дитячого піда?

Я знаю, що можу по-людськи перевірити це в / proc, мені цікаво, чи є розумний / кращий спосіб досягти цього в Ubuntu. Зауважте, що батьків може бути або не можуть бути вбиті.

Дякую

Відповіді:


58

Як отримати батьківський PID (PPID) з ідентифікатора процесу дитини (PID) за допомогою командного рядка

Використовуйте ps -o ppid=

  • наприклад, ps -o ppid= 2072повернення 2061, яке ви можете легко використовувати в скрипті тощо, ps -o ppid= -C fooдає PPID процесу з командою foo. Ви також можете використовувати старомодні ps | grep: ps -eo ppid,comm | grep '[f]oo'.
  • Повніше пояснення: ps -f 2072повертається
    UID PID   PPID   C STIME TTY STAT TIME CMD
    izx 2072   2061   0 07:16? S 0:00 / usr / lib / pulseaudio / pulse / gconf-helper
    
  • pstreeСпіввідношення: pstree -s -p 2072:
    init (1) ───pulseaudio (2061) ───gconf-helper (2072)
    

Чи знаєте ви, як зробити так, щоб pstree показав виклики (команда + аргументи) без розбиття рядків? Моя установка автоматично розбиває рядки, якщо я додаю аргументи, навіть якщо результат може легко вміститися в одному рядку. Сторінка чоловічої сторінки, як видається, говорить стільки ж, але не дає причини. Моє вирішення проблеми передбачає вилучення PID з pstree та використання ps -o args ...результатів, але це має трохи запах.
Іван П

Просто щось, що мене здивувало: простір після, ppid= але перед тим, як виглядає необхідний. Я отримав різні результати, якщо пропустив.
Григорій Ареній

8

Використання лише змінної для отримання батьківського PID:

echo $PPID

якщо вам потрібна команда з цього батьківського піда:

cat /proc/$PPID/comm

якщо вам потрібен повний командний рядок (з усіма параметрами):

cat /proc/$PPID/cmdline

Пояснення

  • $PPID визначається оболонкою, це PID батьківського процесу
  • у /proc/вас є декілька dirs з PID кожного процесу. Потім, якщо ви cat /proc/$PPID/comm, ви повторюєте назву команди PID

Перевірте проц


1
Це найкраща відповідь. procfs - API ядра. виконати команду та проаналізувати вихід - це нісенітниця.
Массімо

Це також потенційно є найбільш портативним, PPIDвизначається як частина стандарту POSIX, тому будь-яка оболонка, сумісна з POSIX, повинна встановлювати це відповідним чином. Дивіться pubs.opengroup.org/onlinepubs/9699919799/utilities/…
RobV

2

Використання pstreeза назвою команди

Використовуючи pstreeви можете здійснювати пошук за іменем дочірнього процесу та отримувати ідентифікатор процесу (PID) разом з батьками, бабусями та дідусями та будь-якими дітьми дитини, які перебувають у процесі:

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

У цьому випадку sleepдочірня команда, і це PID є 8414. Його батьківський ідентифікатор - 841 і називається display-auto-brightness. Бабуся і дідусь - оболонка ( sh) з ідентифікатором процесу 839. Прадід і прадід cronмають ідентифікатор процесу 795. Прадід-прадід також cronмає ідентифікатор процесу 763.

Якщо ви хочете шукати за ідентифікатором процесу sleepзамість імені, ви можете використовувати:

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

Зверніть увагу, sleepідентифікатор процесу змінено на 14653. Батько (PID 841) спить протягом 1 хвилини, прокидається на частку секунди і потім запускає нову sleepкоманду, яка отримує новий ідентифікатор процесу. Це ще одна причина, чому пошук sleepпростіше, ніж пошук за ідентифікатором процесу.

Цей код взятий із: Автоматично регулювати яскравість дисплея на основі сходу та заходу сонця та адаптовано до цього питання.


Щоб побачити вкладений ланцюг увесь шлях до процесу завантаження, використовуйте PID замість імені:

$ 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

Примітка: минула ще хвилина, і команда сну отримує новий PID (8541).


У вашому прикладі цей метод не працював би на процес кронів з PID 807.
Олорін

@Olorin В обох прикладах ви могли би схопитися за 807і, cronі той самий рядок буде повернуто, а також більше дітей, якщо нерестується. Але питання полягало в тому, щоб знайти батька, не всіх дітей.
WinEunuuchs2Unix

Точно - як ти знайдеш батьківський PID 807 з таким висновком? Ви не можете, оскільки це не включає батьків 807.
Олорін

@Olorin Батько хрону є системою, що є PID 1. Я не думаю, що ти можеш вбити PID 1.
WinEunuuchs2Unix

Я нічого не говорив про те, щоб убити щось. Просто для уточнення, тепер ви стверджуєте, що беручи перший рядок pstree або прив'язуючи до імені команди, завжди буде давати батьківський PID?
Олорін

0

ps -efj також можна використовувати для того ж.

Наприклад,

> 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]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.