LINUX.ORG.RU
ФорумAdmin

Как получить pid всех дочерних процессов?

 


0

3

Нужен список pid всех дочерних процессов процесса включая сам процесс. И чтобы список pid нитей тоже включал если можно.

Перемещено hobbit из general



Последнее исправление: bbgg (всего исправлений: 2)
Ответ на: комментарий от bbgg

Если просто список дочерних процессов, то:

ps --pid PID-процесса --ppid PID-процесса -o pid

А если всех процессов ниже по дереву, дочерних от дочерних процессов, то сложно. Там, по идее, нужно циклом обрабатывать вывод:

ps -h --forest -a -x -o pid,ppid 
и смотреть, есть ли ppid в списке, если есть, то печатать процесс и его pid добавлять с список. Может позже напишу.

Конечно, можно обработать вывод ″pstree″, но, если в именах процессов будут запятые, скобки и пр. символы, то сложно вытащить только PID из вывода pstree.

И чтобы список pid нитей тоже включал если можно.

В смысле? У нити pid такой же, как и у процесса. Команде ″ps″ можно указать опцию ″-T″ и тогда будет выводиться ещё и «SPID», но это не PID. У нити не один идентификатор, а пара PID/SPID...

mky ★★★★★
()
Ответ на: комментарий от mky
#!/bin/bash

L=$1
echo $L
ps --no-headers --forest -e -o  pid,ppid | while read P PP; do
    for E in $L; do
        if [ $E == $PP ]; then
            echo $P; L+=" $P"
        fi
    done
done

Но, ps не может нити в дереве показывать. Вот тупое вырезание pid из вывода pstree.

pstree -p PID | tr '-' '\n' | sed -n 's/[^\(]*(\([0-9]\+\))/\1/p'
mky ★★★★★
()
Ответ на: комментарий от mky

В смысле? У нити pid такой же, как и у процесса. Команде ″ps″ можно указать опцию ″-T″ и тогда будет выводиться ещё и «SPID», но это не PID. У нити не один идентификатор, а пара PID/SPID...

Это потому, что в терминах ps pid это алиас для tgid (the process ID of the thread group leader).
top -H показывает pid как pid (In kernel terms, it is a dispatchable entity defined by a task_struct.)

MirandaUser2
()
Ответ на: комментарий от mky

Сложный код для меня. Он рекурсивно читает дочерние процессы?

Помню раньше использовал pstree однострочник, но он почему-то обрывался на каком-то уровне.

Скрипт из интернета. Я подумал возможно proc получше источник чем запуск ps.

!/bin/bash

# root_pid: The PID passed to the script
# That is the PID of the process whose child processes we want to find
root_pid=$1

# all_children: Array that shall store the child processes
declare -A all_children
all_children=()

# Recursive function to find the child processes 
iterate_children()
{
   local pid=$1
   local tids=$(ls /proc/$pid/task)
   # Iterate over all [tid]s in /proc/$pid/task directory
   for tid in $tids
   do
      if [ -e /proc/$pid/task/$tid/children ]
      then
         # Get the child processes in /proc/$pid/task/$tid/children
         local children=$(cat /proc/$pid/task/$tid/children)
         # Iterate over all child processes
         for p in $children
         do
            # Add the found child process to all_children array 
            all_children[${#all_children[@]}]=$p
            # Find the child processes of process $p
            iterate_children $p
         done
      fi
   done
}

iterate_children $root_pid
echo "All child processes of process with PID $root_pid:"
echo ${all_children[*]}
bbgg
() автор топика
Ответ на: комментарий от bbgg

Сложный код

Вы про какой код? То, что написал я просто читает вывод ps, но древовидный, поэтому там потомки всегда ниже родителей, рекурсия не нужна. В приводимом вами скрипте код рекурсивный, но использует файл /proc/PID/task/TID/children. Чтобы этот файл существовал, ядро должно быть с CONFIG_PROC_CHILDREN, вроде, во всех дистрибутивах эта опция включена, но, может где-то и нет.

использовал pstree однострочник

Ну я привёл вариант с pstree, он тоже у вас «обрывается»?

это передать по std в другую программу

Ну можно как вы написали, через bash, можно сделать файл исполняемым и просто запускать. Если передать на std другой программы, то просто палка «|», а если в аргументы другой программы, то через xargs.

mky ★★★★★
()