我在用:
pgrep -P $$
获取 $$ 的子进程 pid。但我实际上也想要一份孙子和曾孙的名单。
我该怎么做呢?例如,使用常规编程语言,我们会使用递归来做到这一点,但是使用 bash 呢?也许使用 bash 函数?
我已经发布了尝试解决方案。它简短而有效,并且似乎符合OP的问题,所以我将保持原样。然而,它存在一些性能和可移植性问题,这意味着它不是一个好的通用解决方案。此代码尝试解决以下问题:
top_pid=$1
# Make a list of all process pids and their parent pids
ps_output=$(ps -e -o pid= -o ppid=)
# Populate a sparse array mapping pids to (string) lists of child pids
children_of=()
while read -r pid ppid ; do
[[ -n $pid && pid -ne ppid ]] && children_of[ppid]+=" $pid"
done <<< "$ps_output"
# Add children to the list of pids until all descendants are found
pids=( "$top_pid" )
unproc_idx=0 # Index of first process whose children have not been added
while (( ${#pids[@]} > unproc_idx )) ; do
pid=${pids[unproc_idx++]} # Get first unprocessed, and advance
pids+=( ${children_of[pid]-} ) # Add child pids (ignore ShellCheck)
done
# Do something with the list of pids (here, just print them)
printf '%s\n' "${pids[@]}"
使用广度优先搜索来构建树的基本方法已被保留,但有关进程的基本信息是通过单次(符合 POSIX 标准)运行获得的ps
. pgrep
不再使用,因为它不在 POSIX 中并且可以运行多次。此外,从队列中删除项目的一种非常低效的方法(复制除其中一个元素之外的所有元素)已被索引变量的操作所取代。
在我的老式 Linux 系统上(大约有 400 个进程)在 pid 0 上运行时,平均(实际)运行时间为 0.050 秒。
我只在 Linux 上测试过它,但它只使用 Bash 3 功能和 POSIX 兼容功能ps
所以它也应该适用于其他系统。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)