假设有一个dummy.sh
pid 为 101 且有七个后代的进程:
pstree -pc 101
dummy(101)──dummy(102)──dummy(103)──dummy(104)──dummy(105)──dummy(106)──sleep(107)
但是如何在 Bash 脚本中获取所有进程的 PID,该脚本有超过 6 个(在我们的示例中为 dummy.sh 101)后代。我不想要子进程的 PID 小于 6。
我尝试过PS -u myuser
,但它只显示所有用户进程。但是如何获取后代大于 6 的用户进程的 PID?
更新:
例如,我使用下面的递归脚本来触发七个直的后代链。我想要获得 PID 101,因为它有超过 6 个后代。
类似地,由于这个虚拟进程是由 bash(100) 终端触发的,该终端将是 dummy(101) 的父级,那么我也想要 Pid 100(因为它也满足拥有超过 6 个后代的条件)。
bash(100)──dummy(101)──dummy(102).....dummy(107)
#!/bin/bash
if [[ "$#" -ne 1 ]]; then
set -- 7
fi
if [[ "$1" -gt 2 ]]; then
echo 'descendant process' "$1"
"$0" "$(($1 - 1))"
else
sleep 500
fi
标准:
我只会考虑命令返回的 PID ps -u $USER -o pid
。因为我的要求只是考虑用户预处理。我将循环它们来查找用户进程是否有超过六个后代,但我的问题是如何找到特定 PID 的后代计数?
答案1
我确信有一种更有效的方法可以做到这一点,但这是有效的:
#!/bin/bash
declare -A procs
ps -u $USER --no-headers -o pid,ppid | (
# build an associate array that maps pids to parent pids
while read pid ppid ; do
procs[$pid]=$ppid
done
# for each process, walk up the tree, counting processes
for pid in "${!procs[@]}"; do
save_pid=$pid
depth=0
while :; do
ppid=${procs[$pid]}
[[ $ppid ]] || break
let depth++
pid=$ppid
done
if (( depth > 6 )); then
echo $save_pid
fi
done
)
答案2
您还可以浏览 /proc 文件系统。对于每个正在运行的进程,都有一个名为“children”的文件,其中所有直接后代都以空格分隔列出。
例如,对于进程 12345,您可以在以下位置找到有关其子进程的信息:
/proc/12345/任务/12345/children