一种至少通过 bash 检查的方法,以防“像这样的情况,我不确切知道子进程的名称”但知道父进程的名称假定是唯一的,可以在 bash 中使用基于ps、grep、sed(为较小的 pid 删除前导空格)、tr(将多个连续的空格压缩为一个)和cut:
$> cat foo_bar.sh
#! /bin/bash
sleep 120
$> ./foo_bar.sh &
[1] 89239
$> ps -eo pid,ppid,args|grep -e " $(ps -eo pid,args| grep foo_bar.sh| grep -v grep| sed s/^\ //g |cut -f 1 -d ' ') "|grep -v foo_bar.sh| sed s/^\ //g | tr -s ' ' | cut -f 1,3 -d ' '
89241 sleep
因此使用父进程的唯一名称来确定父pid:
$> ps -eo pid,args| grep foo_bar.sh| grep -v grep| sed s/^\ //g |cut -f 1 -d ' '
89239
在子进程 ($(...)) 中评估的这个值用于从另一个 ps 调用中 grep 正确的行,以确定子进程和名称的搜索 pid(没有额外的参数并且事先不知道子进程的名字。
注意 - 在 bash 中,一些空格很重要 - 在搜索模式末尾添加的空格:
... grep " $(ps -eo pid,args| grep foo_bar.sh| grep -v grep| cut -f 1 -d ' ') " ...
这有助于避免误报,例如当父 pid 为 123 时,如果不使用空格填充,这将匹配许多包含这些数字的 pid,例如 1234、12345、1123、...
更新(对评论做出反应):如果父进程是a_mama(分叉a_shvili 子进程)并且它是机器上唯一具有该名称的进程,那么以下应该工作:
$> p_proc="a_mama"
$> ps -eo pid,ppid,args|grep -e " $(ps -eo pid,args| grep ${p_proc}| grep -v grep| sed s/^\ //g | cut -f 1 -d ' ') "|grep -v ${p_proc}| sed s/^\ //g | tr -s ' ' | cut -f 1,3 -d ' '
12346 a_shvili