我不需要等待他们,我只需要一个是或否。
我正在执行一个我知道会分叉的程序(孩子们也可能会分叉)。如果运行正确,它应该照顾所有的子级,并在完成时退出它们。我需要编写一个测试来检查这是否属实。孤立进程被分配给 init 进程,因此我无法再在 pstree 中看到它们。
如果我可以获得他们的 PID 列表,这样我就可以向他们发送 SIGKILL,那就加分了。理想情况下,如果它是 POSIX-y 的东西,那么它可以在 *BSD 上工作。
找到这些的一种方法是使用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-id。POSIX在这里提供了一些帮助,但是很容易找到不同的系统 - 并且文档反映了这一点:
-f
。使用 just ps -ef
,它会在第一列中显示进程 ID,而不显示父进程的进程 ID。它需要-l
显示(而不是)user-id 的选项。ps -ef
或ps -efl
)。-l
选项,Solaris 10 将在第一列和第二列中显示进程标志。POSIX 中提到了这一点,尽管标志的内容未指定(因为内容在Unix平台上有所不同)。正如您所看到的,对于可用系统的某些子集,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 使用该术语意味着它们是通过“登录”来的)。
进一步阅读: