2010-04-11 13 views
29

Estoy escribiendo bash script, que hace varias cosas.Cómo matar todos los subprocesos de shell?

Al principio, comienza varias secuencias de comandos de monitor, cada una de ellas ejecuta algunas otras herramientas.

Al final de mi guión principal, me gustaría matar todo lo que surgió de mi caparazón.

Por lo tanto, es posible que se parece a esto:

#!/bin/bash 

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

do_some_work 
... 

kill_subprocesses 

Lo que pasa es que la mayoría de estos monitores desovar sus propios subprocesos, por lo que hacer (por ejemplo): killall some_monitor1.sh no siempre le ayudará.

¿Alguna otra forma de manejar esta situación?

+0

Una gran hilo sobre esto: http://stackoverflow.com/questions/392022/best-way-to-kill-all -child-processes/15139734 # 15139734 – nandinga

Respuesta

18

Después de iniciar cada proceso hijo, puede obtener su id con

ID=$! 

continuación, puede utilizar los PID almacenados para encontrar y matar todos los procesos nieto, etc., como se describe here o here.

+0

Solo para agregar, si los subprocesos de los monitores pueden generar subsubprocesos, etc., necesitarías usar la técnica descrita en el enlace recursivamente. –

+0

@David la 2da página referida incluye una solución para eso. –

+0

Sí, pero ese segundo enlace aún no había aparecido cuando escribí mi comentario. –

8
kill $(jobs -p) 

Rhys Ulerich 's sugerencia:

Advertencia una condición de carrera, usando [código de abajo] logra lo que Jürgen sugirió sin causar un error cuando no existen trabajos

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

Expone una condición de carrera, usando 'test -z' \ 'jobs -p \' "|| kill \ 'jobs -p \' 'logra lo que Jürgen sugirió sin causar un error cuando no hay trabajos –

8

Si usted usa un PID negativo con kill matará a un grupo de procesos.

70
pkill -P $$ 

encajará (simplemente mata a sus propios descendientes)

EDIT: Obtuve un voto negativo, no sé por qué. De todos modos aquí está la ayuda de -P

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

y $$ es la respuesta de pihentagy process id of the script itself

+4

¿Por qué esta respuesta fue downvoted? Parece una respuesta sensata, y estoy considerando usarla. ¿Hay algún inconveniente del que no tengo conocimiento? – MestreLion

+1

Esto funciona para mí en Ubuntu 13.04. –

+0

Gracias por las retroalimentaciones positivas – pihentagy

5

La extensión de matar de forma recursiva todos los descendientes (no sólo niños):

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 
} 

Ahora

kill_descendant_processes $$ 

matará a los descendientes del script/shell actual.

(. Probado en Mac OS 10.9.5 Sólo depende de pgrep y matar)

+2

Bien, pero no use 'kill -9' por defecto, cambie los procesos para salir! http://serverfault.com/a/415744/55046 – pihentagy

Cuestiones relacionadas