Ходить по дереву процессов - PullRequest
13 голосов
/ 07 марта 2011

У меня есть следующий сценарий.

Пользователь должен ввести PID процесса, и сценарий должен показать процесс и его подпроцессы, подпроцессы (и т. Д.) PID, иперечислите это в древовидном формате.

Я пытался использовать pstree PID и ps faux PID, но это не работает.Кажется, что он не принимает PID процессов в качестве аргументов.

Есть идеи, пожалуйста?

Ответы [ 3 ]

26 голосов
/ 15 марта 2011

Просто хотел задокументировать мои шаги, связанные с этой проблемой.

Скажем, я выполняю это в терминале:

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

... и оставляю его в ожидании при вводе read.Затем я всегда могу найти pid mytest.sh, например:

$ 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
...

Затем, скажем, я не хочу «сканировать» gnome-terminal (1489) как родительский, но вместо этого я хочуначинаются с bash (20238) .. Итак, я хотел бы получить этот вывод:

$ 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

... за исключением того, что я не хочу копировать / вставлять дочерние PIDы вручную :)

Я мог бы использовать 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, который я предпочитаю.

Таким образом, я могу использовать pstree просто для получения дочерних PID:

$ 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,

, а затем использовать их для получения ps axf дерева, основываясь только на PID родителя:

$ ps f -p $(pstree -p 20238 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " ")
  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

Ну, надеюсь, это кому-нибудь поможет,
Ура!

2 голосов
/ 07 марта 2011

Это bash-скрипт, использующий только ps и awk .Вы можете использовать в качестве базы для создания дерева процессов.

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
1 голос
/ 07 марта 2011

Ваш первый шаг - передать ps через awk и grep. Используя awk, вы можете изолировать либо поле «этот процесс PID», либо поле «родительский процесс PID».

Или прогуляйтесь по файловой системе / proc.

...