走一棵进程树

时间:2011-03-06 22:39:09

标签: linux shell unix pstree

我有以下情况。

用户将键入进程的PID,脚本应显示进程及其PID的子进程,子进程(等等),并且应以树格式列出。

我尝试使用pstree PIDps faux PID,但它不起作用。看起来它不会将进程的PID作为参数。

有什么想法吗?

3 个答案:

答案 0 :(得分:25)

只想记录与此问题相关的步骤。

假设我在终端中执行此操作:

~$ echo "read -p 'Press Enter'" > mytest.sh
~$ chmod +x mytest.sh
~$ bash -c bash
~$ bash -c ./mytest.sh

...让它等待read输入提示。然后,我总能找到mytest.sh的pid:

$ ps axf | grep mytest
20473 pts/2    S+     0:00              |   |   \_ grep --color=tty mytest
20308 pts/5    S+     0:00              |   |       \_ bash -c ./mytest.sh

...但是,我想输出ps axf树只限于mytest.sh的某个父级;看一个完整的ps axf,我们可以看到一个层次结构:

$ ps axf

 1489 ?        Sl     1:39              \_ gnome-terminal --sm-client-id 106ab86
 1511 ?        S      0:00              |   \_ gnome-pty-helper
...
20238 pts/5    Ss     0:00              |   \_ bash
20274 pts/5    S      0:00              |   |   \_ bash
20308 pts/5    S+     0:00              |   |       \_ bash -c ./mytest.sh
...

然后,说我不想'{1}}(1489)'扫描'为父母,而是我想从gnome-terminal开始(20238)..所以,我想要获得此输出:

bash

...除了,我不想手动复制/粘贴子PID :)

我可以使用$ ps f -p 20238 20274 20308 PID TTY STAT TIME COMMAND 20238 pts/5 Ss 0:00 bash 20274 pts/5 S 0:00 \_ bash 20308 pts/5 S+ 0:00 \_ bash -c ./mytest.sh

pstree

...遗憾的是,输出与$ pstree -a -p 20238 bash,20238 └─bash,20274 └─bash,20308 -c ./mytest.sh $ pstree -p 20238 bash(20238)───bash(20274)───bash(20308) 中的输出并不完全相同,我更喜欢。

所以,我可以简单地使用ps axf获取子PID:

pstree

然后使用它们来获取$ pstree -p 20238 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' 20238 20274 20308 $ pstree -p 20238 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" , 20238,20274,20308, 树,仅基于父级的PID:

ps axf

嗯,希望这有助于某人,
干杯!

答案 1 :(得分:2)

这是仅使用 ps awk 的bash脚本。您可以使用at作为生成流程树的基础。

ppid=$1
while true
do 
    forloop=FALSE
    # get all children by pid 
    for i in `ps -ef | awk '$3 == '$ppid' {print $2}'`
    do 
       # Here you have one of of the elements of tree 
       #   parent -> child
       echo $ppid - $i 
       forloop=TRUE
    done
    ppid=$i

    if [ "$forloop" = "FALSE" ]; then
       exit
    fi
 done

答案 2 :(得分:1)

你的第一步是通过awk和grep管道ps。通过使用awk,您可以隔离“​​此进程PID”字段或“父进程PID”字段。

或者,在/ proc文件系统中漫步。