Comment attendre de tous les enfants (et petits-enfants, etc) processus engendré par un script
Contexte:
Utilisateurs de me fournir leurs scripts à exécuter. Ces scripts peuvent être de toute sorte tels que des scripts pour démarrer plusieurs programmes graphiques, des services back-end. Je n'ai pas de contrôle sur la façon dont les scripts sont écrits. Ces scripts peuvent être de blocage de type c'est à dire l'exécution attend jusqu'à ce que tous les processus enfants (des programmes qui sont exécutés séquentiellement) sortie
#exaple of blocking script
echo "START"
first_program
second_program
echo "DONE"
ou non le blocage de type c'est à dire ceux que la fourche de l'enfant dans le processus d'arrière-plan et la sortie de quelque chose comme
#example of non-blocking script
echo "START"
first_program &
second_program &
echo "DONE"
Que suis-je en train de réaliser?
Utilisateur à condition que les scripts peuvent être de n'importe quel de ces deux types ou mélange des deux. Mon travail consiste à exécuter le script et attendre jusqu'à ce que tout le processus a commencé par la sortie, puis l'arrêt du nœud. Si son de blocage de type, le cas est clair simple c'est à dire obtenir le PID du script processus d'exécution, et attendre jusqu'à ce ps -ef|grep -ef PID n'a pas plus d'entrées. Non-blocage des scripts sont ceux de me donner de la difficulté à
Est-il une manière que je peux obtenir la liste des Pid de tout le processus de l'enfant engendré par l'exécution d'un script? Tous les pointeurs ou conseils seront très appréciés
Merci pour votre réponse, mais je n'ai pas de contrôle sur la façon dont les scripts sont écrits
OriginalL'auteur Ram | 2013-09-06
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser
wait
attendre que tous les processus d'arrière-plan a commencé paruserscript
pour terminer. Depuiswait
ne fonctionne que sur les enfants de l'interpréteur de commandes actuel, vous aurez besoin de source de leur script au lieu de l'exécuter en tant que processus distinct.Sourcing le script explicite shell interne est exécuté doit simuler le démarrage d'un nouveau processus d'assez près. Si non, vous pouvez également arrière-plan le shell interne est exécuté, où les forces d'un nouveau processus a commencé, puis attendre il pour terminer.
Dans le deuxième extrait, avez-vous vraiment besoin d'un shell interne est exécuté? ne serait pas
{ source userscript; wait; } & wait
être assez? (&
origines du groupe...)Le groupe de commandement serait probablement très bien. Je ne me souviens pas mettre trop de pensée en elle d'autre que de fond le premier extrait.
OriginalL'auteur chepner
ps --ppid $PID
liste de tous les processus fils du processus avec$PID
.Oui. Si le parent est d'aller à la sortie, vous devez créer la liste des enfants PIDs avant qu'il n', par exemple dans un fichier.
OriginalL'auteur Ansgar Wiechers
Vous pouvez ouvrir un descripteur de fichier qui obtient héritées par d'autres processus, et ensuite, attendre jusqu'à ce qu'il n'est plus en usage. C'est une faible surcharge de la méthode qui fonctionne généralement à l'amende, s'il est possible pour un processus de travail autour d'elle si ils veulent:
Vous pouvez suivre toutes les invoquée processus, en utilisant ptrace, comme avec
strace
. C'est plus facile, mais a certains frais généraux associés et peut ne pas fonctionner lorsque les scripts invoquer suid binaires:OriginalL'auteur that other guy
Vous pouvez utiliser
pgrep -P <parent_pid>
pour obtenir une liste de processus enfants. Exemple:Et pour obtenir les petits-enfants, il suffit de faire la même procédure sur chaque processus enfant.
Découvrez mon blog Bash fonctions de liste et de tuer ou d'envoyer des signaux aux processus d'arbres.
Vous pouvez utiliser une de ces fonctions correctement la liste de tous les processus engendré en vertu d'un processus. Chacun a sa propre méthode ou de l'ordre d'envoyer des signaux aux processus.
La seule limitation est que le processus de toujours avoir à être connecté et pas orphelins. Si vous pouviez trouver un moyen de le groupe de vos processus, c'est peut-être votre solution.
Ok j'ai fait une mise à jour. Je suis sûr que l'idée de base est suffisante pour faire de cette une réponse valable. Ou bien l'autre réponse ici devrait également être rendue invalide.
OriginalL'auteur konsolebox
De simplement répondre à la question qui a été posée. Vous pouvez stocker l'ID de processus de chaque script que vous êtes d'appel dans la même variable:
$child_process_ids serait juste un espace délimité de la chaîne d'Id de processus. Maintenant, ce qui répond à la question posée, cependant, ce que je ferais serait un peu différent. Je voudrais appeler chaque script à partir d'une boucle for, magasin de son IDENTIFIANT de processus, puis d'attendre sur chacun d'eux dans une autre boucle pour terminer et inspecter chaque code de sortie individuellement. En utilisant le même exemple, voici à quoi il pourrait ressembler.
OriginalL'auteur Jason Slobotski