Как получить идентификатор родительского процесса для данного дочернего процесса?


50

Как получить родительский pid из данного pid детей?

Я знаю, что могу вручную проверить это в / 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-хелперов (2072)
    

Знаете ли вы, как сделать вызовы pstree show (команда + аргументы) без разделения строк? Моя установка автоматически разбивает строки, если я добавляю аргументы, даже если результат может легко поместиться в одну строку. Похоже, что страница руководства говорит об этом, но не дает повода. Мой обходной путь включает извлечение PID из pstree и использование ps -o args ...результатов, но это немного пахнет.
Джон П

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

8

Использование только переменной для получения родительского PID:

echo $PPID

если вам нужна команда из этого родительского pid:

cat /proc/$PPID/comm

если вам нужна полная командная строка (со всеми параметрами):

cat /proc/$PPID/cmdline

объяснение

  • $PPID определяется оболочкой, это PID родительского процесса
  • в /proc/, у вас есть несколько каталогов с PID каждого процесса. Затем, если вы cat /proc/$PPID/comm, вы повторяете имя команды PID

Проверьте man proc


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. Его родительский ID 841 и называется display-auto-brightness. Дедушка - это shell ( 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 вместо name:

$ 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

Примечание. Прошла еще одна минута, и команда sleep получает новый PID (8541).


В вашем примере этот метод не работал бы для процесса cron с PID 807.
Олорин

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

Точно - как найти родителя PID 807 с этим выходом? Вы не можете, потому что это не включает родителя 807.
Олорин

@Olorin Родителем cron является systemd, который является PID 1. Я не думаю, что вы можете убить PID 1.
WinEunuuchs2Unix

Я ничего не говорил об убийстве. Просто чтобы уточнить, теперь вы утверждаете, что взятие первой строки pstree или grepping для имени команды всегда даст родительский 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.