如何获得给定子进程的父进程ID?


49

如何从给定的孩子pid获取父pid?

我知道我可以在/ proc下手动检查它,我想知道在Ubuntu中是否有一种聪明/更好的方法来实现这一点。请注意,父母可能被杀也可能未被杀。

谢谢

Answers:


58

如何使用命令行从子进程的ID(PID)中获取父PID(PPID)

采用 ps -o ppid=

  • 例如ps -o ppid= 2072returns 2061,您可以在脚本中轻松使用等。ps -o ppid= -C foo使用command给出流程的PPID foo。您也可以使用老式的ps | grepps -eo ppid,comm | grep '[f]oo'
  • 更充分的解释:ps -f 2072返回
    UID PID   PPID   C时间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在不分割行的情况下显示调用(命令和参数)的方法?如果添加参数,我的安装会自动分割行,即使结果很容易就适合一行。手册页似乎讲了很多,但没有给出原因。我的解决方法涉及从pstree提取PID并ps -o args ...在结果上使用,但这有点怪味。
约翰·P

只是让我感到惊讶的是:ppid= PID 之后但之前的空间似乎是必需的。如果我省略它,则会得到不同的结果。
格雷戈里·阿雷纽斯

8

仅使用变量获取父PID:

echo $PPID

如果需要此父pid的命令:

cat /proc/$PPID/comm

如果您需要完整的命令行(包括所有选项):

cat /proc/$PPID/cmdline

说明

  • $PPID 由外壳定义,它是父进程的PID
  • 在中/proc/,每个进程的PID都有一些差异。然后,如果您cat /proc/$PPID/comm,则回显PID的命令名称

检查人进程


1
这是最好的答案。procfs是内核API。执行命令并解析输出是胡说八道。
Massimo

它也可能是最便携的,PPID被定义为POSIX标准的一部分,因此任何POSIX兼容的外壳都应对此进行适当设置。见pubs.opengroup.org/onlinepubs/9699919799/utilities/...
RobV

2

使用pstree的命令名称

使用,pstree您可以按子进程名称进行搜索,并获得进程ID(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。祖父母是sh进程ID 为的shell()839。曾祖父母cron的进程标识为795。曾曾祖父母cron的进程ID也为763

如果要按“流程ID” sleep而不是名称进行搜索,可以使用:

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

请注意,sleep进程ID已更改为14653。父级(PID 841)睡眠1分钟,醒来一秒钟,然后启动一个新sleep命令以获取新的进程ID。这是为什么搜索sleep比按进程ID搜索更容易的另一个原因。

该代码摘自:根据日出和日落自动调整显示亮度,并适应此问题。


要查看一直到启动过程的嵌套链,请使用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

注意:又过了一分钟,sleep命令获得一个新的PID(8541)。


在你的榜样,这种方法就不用工作了cron进程PID为807
Olorin

@Olorin在两个示例中,您都可以在807或上进行grep cron渲染,并且会重生同一行以及更多的子级。但问题是要找到父母,而不是所有孩子。
WinEunuuchs2Unix

确实-您如何通过该输出找到PID 807的父级?您不能,因为它不包括807的父母
。– Olorin

@Olorin cron的父级是systemd,它是PID 1。我不认为你能杀了PID 1
WinEunuuchs2Unix

我什么也没杀。只是为了澄清一下,现在您声称采用pstree的第一行或grepping作为命令名将始终提供父PID?
Olorin '18

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]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.