Je voudrais obtenir une liste de tous les processus qui en découlent (par exemple les enfants, les petits-enfants, etc.) $pid
. C'est la manière la plus simple que j'ai trouvée:
pstree -p $pid | tr "\n" " " |sed "s/[^0-9]/ /g" |sed "s/\s\s*/ /g"
Existe-t-il une commande ou un moyen plus simple d'obtenir la liste complète de tous les processus descendants?
'\n'
délimité vs' '
délimité). Le cas d'utilisation pratique est: a) un script démoniseur que j'ai écrit à partir du masochisme pur (en particulier, la fonctionnalité "stop" doit gérer n'importe quelle arborescence de processus engendrée par le processus démonisé); et b) un script de temporisation qui tuera tout ce que le processus de temporisation a réussi à créer.kill
. Voir unix.stackexchange.com/questions/9480/… , unix.stackexchange.com/questions/50555/…ps ax -opid,ppid,pgrp,cmd
Je vois qu'il existe de nombreux processus qui partagent le mêmepgrp
que le sous-arbre exact que je veux tuer. (De plus, je ne vois aucunsetpgrp
programme répertorié dans les paquets stables de Debian: packages.debian.org/… )Réponses:
Ce qui suit est un peu plus simple et présente l'avantage supplémentaire d'ignorer les nombres dans les noms de commande:
Ou avec Perl:
Nous recherchons des nombres entre parenthèses afin de ne pas, par exemple, donner 2 comme processus enfant lorsque nous traversons
gif2png(3012)
. Mais si le nom de la commande contient un nombre entre parenthèses, tous les paris sont désactivés. Il n'y a que jusqu'ici que le traitement de texte puisse vous emmener.Je pense donc aussi que les groupes de processus sont la voie à suivre. Si vous souhaitez qu'un processus s'exécute dans son propre groupe de processus, vous pouvez utiliser l'outil 'pgrphack' du paquet Debian 'daemontools':
Ou vous pouvez à nouveau vous tourner vers Perl:
La seule mise en garde ici est que les groupes de processus ne sont pas imbriqués, donc si un processus crée ses propres groupes de processus, ses sous-processus ne seront plus dans le groupe que vous avez créé.
la source
pstree -lp | grep -Po "(?<=\()\d+(?=\))"
la source
bash
,zsh
,fish
, et mêmeksh 99
), mais pourrait ne pas fonctionner sur des coquilles plus âgés, par exempleksh 88
La version la plus courte que j'ai trouvée qui traite également correctement des commandes telles que
pop3d
:Il traite à tort si vous avez des commandes qui ont des noms étranges comme:
my(23)prog
.la source
ffmpeg
utilisation de threads. Bien que, à partir d' observations rapides, il semble que les fils sont données avec leur nom à l' intérieur des accolades,{ }
.Il y a aussi la question de l'exactitude. L'analyse naïve de la sortie de
pstree
est problématique pour plusieurs raisons:Si Python et le
psutil
package sont installés, vous pouvez utiliser cet extrait pour répertorier tous les processus descendants:(Le package psutil est par exemple installé en tant que dépendance de la
tracer
commande disponible sur Fedora / CentOS.)Alternativement, vous pouvez faire une traversée en largeur de l'arbre de processus dans un shell bourne:
Pour calculer la fermeture transitive d'un pid, la partie de queue peut être omise.
Notez que ce qui précède n'utilise pas la récursivité et s'exécute également dans ksh-88.
Sous Linux, on peut éliminer l'
pgrep
appel et lire à la place les informations de/proc
:Ceci est plus efficace car nous enregistrons un fork / exec pour chaque PID et effectuons un
pgrep
travail supplémentaire à chaque appel.la source
Cette version Linux nécessite uniquement / proc et ps. Il est adapté du dernier morceau de l'excellente réponse de @ maxschlepzig . Cette version lit / proc directement à partir du shell au lieu de générer un sous-processus dans une boucle. C'est un peu plus rapide et sans doute légèrement plus élégant, comme le demande ce titre de fil.
la source
Dans chacun de vos deux cas d'utilisation (apparemment très artificiels), pourquoi voulez-vous tuer des sous-processus de processus malheureux? Comment savez-vous mieux qu'un processus quand ses enfants devraient vivre ou mourir? Cela me semble une mauvaise conception; un processus doit se nettoyer après lui-même.
Si vous savez vraiment mieux, alors vous devriez bifurquer ces sous-processus, et le «processus démonisé» est apparemment trop stupide pour être fiable
fork(2)
.Vous devez éviter de conserver des listes de processus enfants ou de vous déplacer dans l'arborescence des processus, par exemple en plaçant les processus enfants dans un groupe de processus séparé comme suggéré par @Gilles.
Dans tous les cas, je soupçonne que votre processus démonisé serait préférable de créer un pool de threads de travail (qui meurt nécessairement avec son processus contenant) qu'un arbre profond de sous-sous-sous-sous-processus, que quelque chose doit ensuite nettoyer quelque part .
la source
Voici un script wrapper pgrep qui vous permet d'utiliser pgrep et d'obtenir tous les descendants en même temps.
~/bin/pgrep_wrapper
:Appelez de la même manière que vous appelez pgrep normal, de manière
pgrep_recursive -U $USER java
à trouver tous les processus et sous-processus Java de l'utilisateur actuel.la source
IFS
et l'utilisation de tableaux ("${array[*]}
").