这pstree
是一个非常好的解决方案,但是有点沉默寡言。我ps --forest
改用。但不是PID
(-p
),因为它只打印特定的进程,但只打印会话(-g
)。它可以打印出任何信息,ps
可以在定义该-o
选项的漂亮ASCII艺术树中打印。
所以我对这个问题的建议:
ps --forest -o pid,tty,stat,time,cmd -g 2795
如果该过程不是会话负责人,则必须应用更多技巧:
ps --forest -o pid,tty,stat,time,cmd -g $(ps -o sid= -p 2795)
这将首先获取当前进程的会话ID(SID),然后使用该sid再次调用ps。
如果不需要列标题,请在“ -o”选项的每个列定义后添加“ =”,例如:
ps --forest -o pid=,tty=,stat=,time=,cmd= -g $(ps -o sid= -p 2795)
运行示例和结果:
$ ps --forest -o pid=,tty=,stat=,time=,cmd= -g $(ps -o sid= -p 30085)
27950 pts/36 Ss 00:00:00 -bash
30085 pts/36 S+ 00:00:00 \_ /bin/bash ./loop.sh
31888 pts/36 S+ 00:00:00 \_ sleep 5
不幸的是,这不起作用,screen
因为它为每个子屏幕和所有孙子bash设置了sid。
为了获得某个进程产生的所有进程,需要构建整棵树。我用awk。首先,它构建一个包含all的哈希数组PID => ,child,child...
。最后,它调用递归函数以提取给定进程的所有子进程。结果将传递给另一个ps
以格式化结果。实际的PID必须写为awk的参数,而不是<PID>
:
ps --forest $(ps -e --no-header -o pid,ppid|awk -vp=<PID> 'function r(s){print s;s=a[s];while(s){sub(",","",s);t=s;sub(",.*","",t);sub("[0-9]+","",s);r(t)}}{a[$2]=a[$2]","$1}END{r(p)}')
对于SCREEN进程(pid = 8041),示例输出如下所示:
PID TTY STAT TIME COMMAND
8041 ? Ss 0:00 SCREEN
8042 pts/8 Ss 0:00 \_ /bin/bash
8092 pts/8 T 0:00 \_ vim test_arg test_server
12473 pts/8 T 0:00 \_ vim
12972 pts/8 T 0:00 \_ vim
ps auxf
。