2010-04-11 7 views
29

J'écris un script bash, qui fait plusieurs choses. Au début, il démarre plusieurs scripts de contrôle, chacun d'entre eux exécute d'autres outils.Comment tuer tous les sous-processus de shell?

A la fin de mon script principal, j'aimerais tuer toutes les choses qui ont surgi de mon shell.

Ainsi, il pourrait ressemble à ceci:

#!/bin/bash 

some_monitor1.sh & 
some_monitor2.sh & 
some_monitor3.sh & 

do_some_work 
... 

kill_subprocesses 

La chose est que la plupart de ces moniteurs frayer leur propre sous-processus, le faire (par exemple): killall some_monitor1.sh ne sera pas toujours aider.

Une autre façon de gérer cette situation?

+0

Un grand fil à ce sujet: http://stackoverflow.com/questions/392022/best-way-to-kill-all -child-processes/15139734 # 15139734 – nandinga

Répondre

18

Après le démarrage de chaque processus enfant, vous pouvez obtenir son id avec

ID=$! 

Ensuite, vous pouvez utiliser les PIDs stockés pour trouver et tuer tous les processus petits-enfants, etc., comme décrit here ou here.

+0

Juste pour ajouter, si les sous-processus des moniteurs peuvent engendrer des sous-processus, etc., vous devrez utiliser la technique décrite dans le lien récursivement. –

+0

@David la 2ème page référencée inclut une solution pour cela. –

+0

Oui, mais ce deuxième lien n'était pas encore apparu lorsque j'ai écrit mon commentaire. –

8
kill $(jobs -p) 

suggestion Rhys Ulerich:

caveat une condition de course, en utilisant [code ci-dessous] accomplit ce que Jürgen a suggéré sans provoquer une erreur quand aucun emploi existe

[[ -z "$(jobs -p)" ]] || kill $(jobs -p) 
+3

Annule une condition de concurrence en utilisant 'test -z' \ 'jobs -p \' "|| kill \ 'jobs -p \' 'accomplit ce que Jürgen a suggéré sans causer d'erreur quand il n'y a pas d'emploi –

8

Si vous utilisez un PID négatif avec kill il va tuer un groupe de processus.

70
pkill -P $$ 

ira (tue juste ses propres descendants)

EDIT: J'ai reçu un downvote, je ne sais pas pourquoi. Quoi qu'il en soit voici l'aide -P

-P, --parent ppid,... 
      Only match processes whose parent process ID is listed. 

et $$ est le process id of the script itself

+4

Pourquoi cette réponse a-t-elle été refusée? Cela semble être une réponse sensée, et j'envisage de l'utiliser. Y a-t-il des inconvénients que je ne connais pas? – MestreLion

+1

Cela fonctionne pour moi sur Ubuntu 13.04. –

+0

Merci pour les commentaires positifs – pihentagy

5

Extension réponse à tuer récursive tous les descendants de pihentagy (pas seulement les enfants):

kill_descendant_processes() { 
    local pid="$1" 
    local and_self="${2:-false}" 
    if children="$(pgrep -P "$pid")"; then 
     for child in $children; do 
      kill_descendant_processes "$child" true 
     done 
    fi 
    if [[ "$and_self" == true ]]; then 
     kill -9 "$pid" 
    fi 
} 

maintenant

kill_descendant_processes $$ 

va tuer des descedants du script/shell actuel.

(. Testé sous Mac OS 10.9.5 ne dépend pgrep et de tuer)

+2

Ok, mais s'il vous plaît ne pas utiliser 'kill -9'" par défaut ", changer les processus pour sortir! http://serverfault.com/a/415744/55046 – pihentagy

Questions connexes