Ходить по дереву процессов
У меня есть следующий сценарий.
Пользователь вводит PID процесса, и сценарий должен показывать процесс и его подпроцессы, подпроцессы (и т. Д.) PID, и он должен перечислять его в древовидном формате.
Я пытался с помощью pstree PID
а также ps faux PID
, но это не работает. Кажется, что он не принимает PID процессов в качестве аргументов.
Есть идеи, пожалуйста?
3 ответа
Просто хотел документировать мои шаги, связанные с этой проблемой.
Скажем, я выполняю это в терминале:
~$ echo "read -p 'Press Enter'" > mytest.sh
~$ chmod +x mytest.sh
~$ bash -c bash
~$ bash -c ./mytest.sh
... и оставить его в ожидании read
подсказка ввода. Тогда я всегда могу найти пид 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
... кроме того, я не хочу копировать / вставлять дочерние идентификаторы вручную:)
Я мог бы использовать 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
Ну, надеюсь, это поможет кому-то,
Ура!
Это скрипт 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
Ваш первый шаг - передать ps через awk и grep. Используя awk, вы можете изолировать либо поле "этот процесс PID", либо поле "родительский процесс PID".
Или прогуляйтесь по файловой системе /proc.