pstree是以树状图直观展示进程父子关系的专用命令,默认以systemd(1)为根,支持-p显示PID、-s追溯父链、-u标注用户,比ps更高效准确。

直接用 pstree,别先跑 ps 再手动拼 PPID —— 那是把家谱拆成散页再一张张对,效率低还容易漏。
用 pstree -p 看 PID 和父子层级
默认 pstree 只显示进程名和缩进,但实际调试时你得知道哪个是哪个 PID。加 -p 是刚需:
pstree -p会在每个进程名后带上括号里的 PID,比如sshd(1234)───bash(1256)───vim(1289)- 缩进深度 = 父子层级数,最左顶格一般是
systemd(1)或init(1),它是整棵树的根 - 注意带方括号的条目,如
[kthreadd]或[{nginx}],前者是内核线程,后者是用户态线程(不是独立进程)
用 pstree -s 追溯单个进程的父链
如果已经拿到了某个可疑进程的 PID(比如通过 ps aux | grep xxx 查到的 5678),接下来想尽快判断它究竟是由某个服务拉起的,还是只是被临时脚本 spawn 出来的,这时候直接用 -s 就够了:
pstree -s 5678输出类似:systemd(1)───sshd(895)───sshd(1023)───bash(1042)───python3(5678)- 它不展示兄弟进程,只往上翻父进程链,路径清晰,避免干扰
- 如果输出里出现
systemd(1)───dockerd(123)───containerd(456)───runc(789),说明这进程在容器里,不是宿主机直启的
用 pstree -u 和用户名过滤缩小范围
多用户环境(比如共享服务器、CI runner)下,光看进程名没用,nginx 可能是 root 启的,也可能是 www-data 启的。加 -u 能立刻区分归属:
pstree -u会在进程名后加@username,如nginx@www-data、node@deploy- 聚焦某用户全部进程:直接
pstree -u deploy,不用再套grep—— 后者会把grep自己也列进去,造成干扰 - 注意:如果某进程 UID 和启动用户不一致(比如 setuid 程序),
pstree -u显示的是实际运行 UID,不是启动者
别依赖 ps -ef --forest 当主力工具
ps -ef --forest 确实也能画树,但它本质还是表格,靠 ASCII 符号模拟缩进,一屏超过 20 行就容易看串行;而且默认不带 PID、不标用户,要补参数才勉强可用:
ps -eo pid,ppid,comm,user --forest | grep -v "grep"才能接近pstree -p -u效果,但命令长、易出错ps的 PPID 列是数值,没法直接看出“谁启动了谁”,得自己顺着数字往上查,遇到孤儿进程(PPID=1)或 init 收养的进程容易误判来源pstree是专为父子关系设计的,底层直接读/proc/[pid]/stat的ppid字段并递归构建树,比ps少一层解析开销
真正棘手的,从来不是命令本身怎么输入,而是拿到树形输出之后,顺手就把方括号里的线程忽略了,把 containerd 当成普通进程看,或者直接认定 PPID=1 就一定是 init 直接拉起——这些细节一旦没盯紧,父子关系基本就等于白看。