测试进程是否留下任何孤儿进程

M.K*_*.K. 3 process

我不需要等待他们,我只需要一个是或否。

我正在执行一个我知道会分叉的程序(孩子们也可能会分叉)。如果运行正确,它应该照顾所有的子级,并在完成时退出它们。我需要编写一个测试来检查这是否属实。孤立进程被分配给 init 进程,因此我无法再在 pstree 中看到它们。

如果我可以获得他们的 PID 列表,这样我就可以向他们发送 SIGKILL,那就加分了。理想情况下,如果它是 POSIX-y 的东西,那么它可以在 *BSD 上工作。

Tho*_*key 5

找到这些的一种方法是使用ps -ef,查找parent-id 为“1”的行,例如,

#!/bin/sh
orphans="$(ps -ef | awk '$3 == 1{ print $2; }')"
echo "Processes which might be orphans: $orphans"
Run Code Online (Sandbox Code Playgroud)

然而,许多进程都将“1”作为其父进程。确定您感兴趣的最好方法是记住您的程序创建的子进程。

如果您碰巧知道创建这些进程的登录名(和/或user-id ),则可以消除一些可能性。第一列ps可以显示(取决于系统类型)登录名或相应的user-idPOSIX在这里提供了一些帮助,但是很容易找到不同的系统 - 并且文档反映了这一点:

  • 例如,FreeBSD 10 不显示该选项的登录名-f。使用 just ps -ef,它会在第一列中显示进程 ID,而不显示父进程的进程 ID。它需要-l显示(而不是)user-id 的选项。
  • OSX 在任一情况下都会给出用户 ID(ps -efps -efl)。
  • 如果有该-l选项,Solaris 10 将在第一列和第二列中显示进程标志。POSIX 中提到了这一点,尽管标志的内容未指定(因为内容在Unix平台上有所不同)。
  • Linux 按照 POSIX 提供登录名和进程标志。

正如您所看到的,对于可用系统的某些子集,ps -efl前三列将给出“相同”的结果。对于更一般的内容,您必须查看标题(第一行)并确定哪一列包含与进程所有者(登录名用户 ID)以及进程 ID 及其父进程 ID 相对应的信息。

对于给定的系统(知道 的可用选项ps,并知道是否匹配登录名用户 ID),您也可以使用awk来匹配字段,例如,

#!/bin/sh
orphans="$(ps -ef | awk -v user=$LOGNAME '($1 == user && $3 == 1){ print $2; }')"
echo "Processes which might be orphans: $orphans"
Run Code Online (Sandbox Code Playgroud)

在这里,我使用$LOGNAME, 来解释 POSIX 对术语“登录名”的使用,这可能会产生误导(因为原则上流程可以通过sudo,而 POSIX 使用该术语意味着它们是通过“登录”来的)。

进一步阅读: