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

Как я могу получить идентификатор процесса родителя текущего процесса?
В общем случае, учитывая идентификатор процесса, как я могу получить идентификатор его родительского процесса?
например. os.getpid() можно использовать для получения идентификатора процесса и os.getppid() для родителя, как мне получить дедушку и бабушку,

Моя цель - linux (ubuntu), поэтому ответы на конкретные платформы в порядке.


person Anurag Uniyal    schedule 13.11.2009    source источник
comment
да и лучше было бы os.pnid(pid, N) или просто os.getppid(pid)   -  person Anurag Uniyal    schedule 13.11.2009


Ответы (7)


специфичный для линукса:

os.popen("ps -p %d -oppid=" % os.getppid()).read().strip()
person pixelbeat    schedule 13.11.2009
comment
Естественно, это не работает в Windows, если у вас не установлен cygwin. - person ddaa; 13.11.2009

С помощью psutil ( https://github.com/giampaolo/psutil):

>>> import psutil
>>> psutil.Process().ppid()
2335
>>> psutil.Process().parent()
<psutil.Process (pid=2335, name='bash', cmdline='bash') at 140052120886608>
>>> 
person Giampaolo Rodolà    schedule 19.11.2010
comment
Это гораздо более надежный ответ, psutil спасает жизнь. - person blented; 03.10.2013
comment
это должно быть os.getppid() вместо os.getpid(). Используйте os.getppid() вместо psutil.Process(os.getpid()).ppid() (чтобы вернуть родительский pid). Чтобы получить идентификатор прародителя процесса, как спрашивает OP, используйте psutil.Process(os.getppid()).ppid() (обратите внимание: getppid(), а не getpid()). - person jfs; 17.02.2016

Я не думаю, что вы можете сделать это в переносном стиле Python. Но есть две возможности.

  1. Информация доступна из команды ps, поэтому вы можете ее проанализировать.
  2. Если у вас есть система с файловыми системами proc, вы можете открыть файл /proc/<pid>/status и найти строку, содержащую PPid:, а затем сделать то же самое для этого PID.

Например, следующий скрипт предоставит вам ваши PID, PPID и PPPID с разрешениями:

#!/bin/bash
pid=$$
ppid=$(grep PPid: /proc/${pid}/status | awk '{print $2'})
pppid=$(grep PPid: /proc/${ppid}/status | awk '{print $2'})
echo ${pid} ${ppid} ${pppid}
ps -f -p "${pid},${ppid},${pppid}"

производит:

3269 3160 3142
UID        PID  PPID  C STIME TTY          TIME CMD
pax       3142  2786  0 18:24 pts/1    00:00:00 bash
root      3160  3142  0 18:24 pts/1    00:00:00 bash
root      3269  3160  0 18:34 pts/1    00:00:00 /bin/bash ./getem.sh

Очевидно, вам придется открывать эти файлы с помощью Python.

person paxdiablo    schedule 13.11.2009
comment
+1 хороший рабочий пример, но ответ pixelbeat работает легко, есть какие-то предостережения? - person Anurag Uniyal; 13.11.2009
comment
Нет, pixelbeat выглядит нормально, и, на самом деле, я проголосовал за него, так как он немного проще, чем мой метод — я не знал об этих опциях для ps, так как пришел из очень ранних дней UNIX. :-) - person paxdiablo; 13.11.2009
comment
Я отредактировал ваш ответ (строка ps). Использование grep для фильтрации вывода ps может дать неправильные результаты (например, если бы pppid был равен 1). Опция -p, кстати, довольно старая. - person tzot; 14.11.2009
comment
Никаких проблем, ΤΖΩΤΖΙΟΥ, это было просто для того, чтобы показать, что три цифры были правильными, а не частью ответа. Но с этого момента я буду использовать эту опцию -p вместо grep. - person paxdiablo; 14.11.2009

Я не думаю, что вы можете сделать это переносимо в общем случае.

Вам необходимо получить эту информацию из списка процессов (например, с помощью команды ps), которая получается специфичным для системы способом.

person ddaa    schedule 13.11.2009
comment
не думаю, что он заботится о переносимости - person Matt Joiner; 23.11.2009

Если у вас есть POSIX-совместимая команда ps, которая позволяет указать нужные столбцы, например: ps -o pid,ppid

Затем вы можете попробовать:

import os
import re

ps = os.popen("ps -o pid,ppid")
ps.readline()    # discard header
lines = ps.readlines()
ps.close

procs = [ re.split("\s+", line.strip()) for line in lines ]

parent = {}
for proc in procs:
    parent[ int(proc[0]) ] = int(proc[1])

Теперь вы можете сделать:

parent[ parent[pid] ]

Вы даже можете написать функцию для вывода списка предков процесса:

def listp(pid):
    print(pid)
    if parent.has_key(pid):
        listp( parent[pid] )
person Nick Dixon    schedule 13.11.2009
comment
line.split() будет работать вместо re.split(r\s+, line.strip()). Функция split() по умолчанию разбивается на \s+ и удаляет начальные и конечные пробелы. - person Andrew Dalke; 13.11.2009

Я искал это для задания и не нашел то, что искал, поэтому я опубликую здесь. Я знаю, что это очень очевидно, но на мгновение это поставило меня в тупик. Если вы тот, кто пишет код дедушки и бабушки, вы можете просто:

#include <stdio.h>
#include <sys/types.h>
#include<sys/wait.h>
#include <unistd.h>

int main(void) {
  int grandpa = getpid();
  int id = fork();
  if (id == 0) {
    int id2 = fork();
    if (id2 == 0) {
      printf("I am the child process C and my pid is %d. My parent P has pid %d. My grandparent G has pid %d.\n", getpid(), getppid(), grandpa);
    } else {
      wait(NULL);
      printf("I am the parent process P and my pid is %d. My parent G has pid %d.\n", getpid(), getppid());
    }
  } else {
    wait(NULL);
    printf("I am the grandparent process G and my pid is %d.\n", getpid());
  }
}
person ganondork    schedule 31.05.2021

person    schedule
comment
Кстати, меня часто спрашивали, почему я не следую PEP-8 и никогда не использую пробел после имени при назначении ему; это старая привычка, которую я разработал для кода C и сохранил ее; Прошли годы с тех пор, как меня в последний раз укусила ошибка = вместо == (или синтаксическая ошибка). - person tzot; 14.11.2009
comment
+1 для pnid, но не будет рекурсивным ps -p %d -oppid= % pid будет намного короче и понятнее - person Anurag Uniyal; 14.11.2009
comment
Это скрипт Python с одним процессом; Я нахожу рекурсивное ps более подходящим для сценария оболочки. Я не рассматриваю python как универсальную замену /bin/sh. В любом случае, спасибо за +1 в вашем комментарии. - person tzot; 14.11.2009