53 votes

ps : Comment obtenir récursivement tous les processus enfants pour un pid donné ?

Comment puis-je obtenir l'affichage de toute l'arborescence des processus générés par un processus donné sous forme d'arbre, et uniquement cet arbre, c'est-à-dire aucun autre processus ?

Le résultat pourrait par exemple ressembler à

 4378 ?        Ss     0:10 SCREEN
 4897 pts/16   Ss     0:00  \_ -/bin/bash
25667 pts/16   S+     0:00  |   \_ git diff
25669 pts/16   S+     0:00  |       \_ less -FRSX
11118 pts/32   Ss+    0:00  \_ -/bin/bash
11123 pts/32   S+     0:00      \_ vi

Je n'ai pas pu obtenir le résultat souhaité uniquement avec les paramètres de ps .

La méthode suivante donne le résultat souhaité mais semble un peu compliquée :

#!/bin/bash

pidtree() {
  echo -n $1 " "
  for _child in $(ps -o pid --no-headers --ppid $1); do
    echo -n $_child `pidtree $_child` " "
  done
}

ps f `pidtree 4378`

Quelqu'un a-t-il une solution plus simple ?

3voto

Philippe A. Points 242

Je me suis efforcé de trouver une solution au même problème. Fondamentalement, la page de manuel de ps ne documente aucune option permettant de faire ce que nous voulons avec une seule commande. Conclusion : un script est nécessaire.

J'ai trouvé un script très similaire au vôtre. Je l'ai collé dans mon ~/.bashrc pour pouvoir l'utiliser depuis n'importe quel script.

pidtree() {
  local parent=$1
  local list=
  while [ "$parent" ] ; do     
    if [ -n "$list" ] ; then
      list="$list,$parent"
    else
      list="$parent"
    fi
    parent=$(ps --ppid $parent -o pid h)
  done
  ps -f -p $list f
}

2voto

Ole Tange Points 4059

Cela ne donne que les pids pid+children, chacun sur une ligne, ce qui est utile pour la suite du traitement.

pidtree() {
    for _pid in "$@"; do
        echo $_pid
        pidtree `ps --ppid $_pid -o pid h`
    done
}

Avec une meilleure disposition des arbres :

_pidtree() {
    local p="$1"
    shift
    for _pid in "$@"; do
        echo "$p$_pid"
        _pidtree " $p" `ps --ppid $_pid -o pid h`
    done
}
pidtree() {
    _pidtree '' "$@"
}

1voto

Shakiba Moshiri Points 171

On way sur la ligne de commande :

ps -o time,pid,ppid,cmd --forest -g -p $(pgrep -x bash)

qu'il produit :

    TIME   PID  PPID CMD
00:00:00  5484  5480 bash
00:00:01  5531  5484  \_ emacs -nw .bashrc
00:00:01  2986  2984 /bin/bash
00:00:00  4731  2986  \_ redshift
00:00:00  5543  2986  \_ ps -o time,pid,ppid,cmd --forest -g -p 2986 5484

Une façon plus élégante de procéder consiste à définir une fonction en .bashrc :

function subps()                                                                                    
{                                                                                                   
    process=$(pgrep -x $1)                                                                                                                                                                     
    ps -o time,pid,ppid,cmd --forest -g -p $process                                                 
}    

puis sur la ligne de commande :

subps bash

1voto

vipin bansal Points 96

Vous pouvez obtenir le pids de tous les processus enfants d'un processus parent donné <pid> en lisant le /proc/<pid>/task/<tid>/children entrée.

Ce fichier contient les pids des processus enfants de premier niveau. Recursivement, vous pouvez également voir les processus enfants.

Pour plus d'informations, consultez le site https://lwn.net/Articles/475688/

0voto

initzero Points 534

J'ai créé un script similaire basé sur celui de Philippe ci-dessus

pidlist() {
local thispid=$1
local fulllist=
local childlist=
childlist=$(ps --ppid $thispid -o pid h)
for pid in $childlist
do
  fulllist="$(pidlist $pid) $fulllist"
done
echo "$thispid $fulllist"
}

Cela permet d'obtenir tous les pids des enfants, petits-enfants, etc. dans un format délimité par des espaces. Ce format peut, à son tour, être transmis à ps, comme dans l'exemple suivant

ps -p $(pidlist *pid*)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X