如何仅用ps命令获取当前进程所有父进程的命令列表?
仅用ps命令获取指定进程的完整父进程链(含自身)
我熟悉以下命令的用法:
$ sudo ps -ef f $ pstree
但它们会输出系统中所有进程的树状结构。我希望仅使用ps命令,获取指定进程的所有父进程(包含该进程自身)的命令及参数列表,并按从根父进程到目标进程的层级顺序排列。
示例场景
假设系统进程树片段如下:
root 6334 1 0 15:48 ? Sl 0:01 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 4b8ff8e11a38cf3c7ec6d8259014f494c5e8628306ae16906826d867324e4afc -address /run/containerd/containerd. root 6393 6334 0 15:48 ? Ss 0:00 \_ /package/admin/s6/command/s6-svscan -d4 -- /run/service root 6929 6393 0 15:48 ? S 0:00 \_ s6-supervise s6-linux-init-shutdownd root 6940 6929 0 15:48 ? Ss 0:00 | \_ /package/admin/s6-linux-init/command/s6-linux-init-shutdownd -c /run/s6/basedir -g 3000 -C -B root 7256 6393 0 15:48 ? S 0:00 \_ s6-supervise s6rc-oneshot-runner root 7288 7256 0 15:48 ? Ss 0:00 | \_ /package/admin/s6/command/s6-ipcserverd -1 -- /package/admin/s6/command/s6-ipcserver-access -v0 -E -l0 -i data/rules -- /package/admin/s6/comm root 7257 6393 0 15:48 ? S 0:00 \_ s6-supervise s6rc-fdholder root 7258 6393 0 15:48 ? S 0:00 \_ s6-supervise svc-bazarr nacho 7578 7258 0 15:48 ? Ss 0:00 \_ python3 /app/bazarr/bin/bazarr.py --no-update --config /config nacho 7825 7578 0 15:48 ? Sl 0:33 \_ /usr/bin/python3 -u /app/bazarr/bin/bazarr/main.py --no-update --config /config root 6373 1 0 15:48 ? Sl 0:01 /usr/bin/containerd-shim-runc-v2 -namespace moby -id a67ced46f899d8359864da27ff51aae53d32d3d68fd1383fbcf64ca4bcf523ba -address /run/containerd/containerd. root 6401 6373 0 15:48 ? Ss 0:00 \_ /package/admin/s6/command/s6-svscan -d4 -- /run/service root 6623 6401 0 15:48 ? S 0:00 \_ s6-supervise s6-linux-init-shutdownd root 6626 6623 0 15:48 ? Ss 0:00 | \_ /package/admin/s6-linux-init/command/s6-linux-init-shutdownd -c /run/s6/basedir -g 3000 -C -B root 6733 6401 0 15:48 ? S 0:00 \_ s6-supervise s6rc-oneshot-runner root 6769 6733 0 15:48 ? Ss 0:00 | \_ /package/admin/s6/command/s6-ipcserverd -1 -- /package/admin/s6/command/s6-ipcserver-access -v0 -E -l0 -i data/rules -- /package/admin/s6/comm root 6734 6401 0 15:48 ? S 0:00 \_ s6-supervise s6rc-fdholder root 6735 6401 0 15:48 ? S 0:00 \_ s6-supervise svc-de nacho 7107 6735 0 15:48 ? Ss 0:00 | \_ /bin/bash /defaults/startwm.sh nacho 7142 7107 0 15:48 ? S 0:00 | \_ /usr/bin/openbox --startup /usr/libexec/openbox-autostart OPENBOX nacho 7826 7142 0 15:48 ? S 0:00 | \_ /bin/sh /usr/libexec/openbox-autostart OPENBOX nacho 7831 7826 0 15:48 ? S 0:00 | \_ sh /config/.config/openbox/autostart nacho 7832 7831 0 15:48 ? Sl 0:52 | \_ /usr/lib/firefox/firefox nacho 8043 7832 0 15:48 ? Sl 0:00 | \_ /usr/lib/firefox/firefox -contentproc -parentBuildID 20230802111331 -prefsLen 28349 -prefMapSize 232511 -appDir /usr/lib/f nacho 8092 7832 0 15:48 ? Sl 0:01 | \_ /usr/lib/firefox/firefox -contentproc -childID 1 -isForBrowser -prefsLen 28425 -prefMapSize 232511 -jsInitLen 242676 -pare nacho 8179 7832 0 15:48 ? Sl 0:00 | \_ /usr/lib/firefox/firefox -contentproc -childID 2 -isForBrowser -prefsLen 32965 -prefMapSize 232511 -jsInitLen 242676 -pare nacho 8215 7832 0 15:48 ? Sl 0:00 | \_ /usr/lib/firefox/firefox -contentproc -childID 3 -isForBrowser -prefsLen 29163 -prefMapSize 232511 -jsInitLen 242676 -pare nacho 8241 7832 0 15:48 ? Sl 0:00 | \_ /usr/lib/firefox/firefox -contentproc -childID 4 -isForBrowser -prefsLen 29163 -prefMapSize 232511 -jsInitLen 242676 -pare nacho 8245 7832 0 15:48 ? Sl 0:00 | \_ /usr/lib/firefox/firefox -contentproc -childID 5 -isForBrowser -prefsLen 291
当目标进程PID为8179时,期望输出如下:
/usr/bin/containerd-shim-runc-v2 -namespace moby -id a67ced46f899d8359864da27ff51aae53d32d3d68fd1383fbcf64ca4bcf523ba -address /run/containerd/containerd. /package/admin/s6/command/s6-svscan -d4 -- /run/service s6-supervise svc-de /bin/bash /defaults/startwm.sh /usr/bin/openbox --startup /usr/libexec/openbox-autostart OPENBOX /bin/sh /usr/libexec/openbox-autostart OPENBOX sh /config/.config/openbox/autostart /usr/lib/firefox/firefox /usr/lib/firefox/firefox -contentproc -childID 2 -isForBrowser -prefsLen 32965 -prefMapSize 232511 -jsInitLen 242676 -pare
实现方法
通过循环调用ps命令,从目标PID开始逐层向上获取父进程(PPID),直到到达系统初始进程,最后反转结果得到从根到目标进程的顺序:
- 在shell中定义如下函数:
get_parent_chain() { local pid=$1 local chain=() while [[ $pid -ne 0 ]]; do # 获取当前进程的完整命令行 cmd=$(ps -o cmd= -p "$pid") # 获取当前进程的父PID ppid=$(ps -o ppid= -p "$pid" | tr -d ' ') chain+=("$cmd") pid=$ppid # 避免针对init进程的无限循环 if [[ $pid -eq $(ps -o ppid= -p "$pid" | tr -d ' ') ]]; then break fi done # 反转数组,输出从根父进程到目标进程的顺序 for ((i=${#chain[@]}-1; i>=0; i--)); do echo "${chain[i]}" done }
- 使用时直接传入目标PID:
get_parent_chain 8179
该方法完全依赖ps命令,无需其他工具,输出结果严格符合层级顺序要求。
内容的提问来源于stack exchange,提问作者IMTheNachoMan
相关产品推荐
相关产品推荐

