Halloween en Linux: cómo matar procesos zombie

estampa de Halloween

Llega el día de los difuntos y por eso queremos hacer desde LxA este pequeño tutorial para hablar de los procesos zombie y de cómo podemos matarlos. Lo primero decir qué es eso de proceso zombie, y es que como sabrás el kernel Linux tiene un subsistema para gestionar los procesos y trabaja con el scheduler para crear, variar la prioridad, enviar o sacar del flujo de procesamiento de la CPU y matar procesos. Pues bien, esta parte del kernel, como el resto de sistemas tipo Unix, distingue entre varios estados de procesos…

Así nos podemos encontrar que un proceso puede estar en estado sleeping (S), es decir, dormido. También procesos en estado running (R) que son aquellos que están en marcha o ejecución actualmente, procesos waiting (D) que están detenidos a la espera de ser atendidos, gestopt (T) o suspendidos, y también los zombie (Z) o difuntos. Un proceso zombie o difunto es aquel que ya ha sido terminado con éxito, pero que tiene secuestrados ciertos recursos del sistema puesto que Linux aún lo está guardando en la tabla de procesos. Ya sabes que cuando un proceso termina, no debería quedarse en este estado, sino que se completa y el kernel libera los recursos para que otros procesos puedan usarlos, básicamente libera la memoria RAM ocupada…

Pues bien, como no interesa tener este tipo de procesos zombie, aunque no sean tan frecuentes, podemos buscarlos y eliminarlos como indicamos aquí. Lo primero es encontrar si existen procesos zombie en nuestra distro y para eso nos podemos ayudar de herramientas como top o como ps. Por ejemplo, alguna de estas dos opciones:


ps -el | grep 'Z'

ps aux | grep defunct

Y una vez detectado, podemos matarlo directamente con:


kill -HUP `ps -A -ostat,ppid,pid,cmd | grep -e ‘^[Zz]’ | awk ‘{print $2}’`

Aunque otra alternativa es encontrar a los procesos padre, puesto que para matar a un proceso zombie hay que matar a los procesos padre que lo sustentan como habréis podido deducir:


ps -eo pid,ppid | grep <PID>

kill -9 <PPID>

Tendrás que sustituir <PID> por el ID del proceso zombie que hayas encontrado y para matarlo con kill, usar el ID del proceso padre sustituyendo <PPID> en el ejemplo, evidentemente.


Deja tu comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: AB Internet Networks 2008 SL
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.

  1.   hecho bolas dijo

    ¡Buen sitio!
    Siempre nos sacan del apuro.

    Donde dice:
    Aunque otra alternativa es encontrar a los procesos padre, puesto que para matar a un proceso zombie hay que matar a los procesos padre que lo sustentan como habréis podido deducir:

    1| ps -eo pid,ppid | grep
    2|
    3| kill -9

    Tendrás que sustituir por el ID del proceso zombie que hayas encontrado y para matarlo con kill, usar el ID del proceso padre sustituyendo en el ejemplo, evidentemente.

    se puede agregar el script:

    $ cat killppid.sh
    #!/bin/bash
    kill -9 $(ps -eo pid,ppid | awk ‘$1==’${1}’ {print $2}’)

    claro que no es una tarea que un usuario normal realice a cada rato.
    Sólo sería de utilidad para el administrador, pero es peligroso correrlo como root, porque se puede matar cualquier proceso del sistema.

    En man kill tiene esta nota:

    NOTES Your shell (command line interpreter) may have a built-in kill command. You may
    need to run the command described here as /bin/kill to solve the conflict.

    Bash tiene ese comando, esta es la parte de man bash al respecto:

    kill [-s sigspec | -n signum | -sigspec] [pid | jobspec] …
    kill -l|-L [sigspec | exit_status]
    Send the signal named by sigspec or signum to the processes named by pid or job‐
    spec. sigspec is either a case-insensitive signal name such as SIGKILL (with or
    without the SIG prefix) or a signal number; signum is a signal number. If
    sigspec is not present, then SIGTERM is assumed. An argument of -l lists the
    signal names. If any arguments are supplied when -l is given, the names of the
    signals corresponding to the arguments are listed, and the return status is 0.
    The exit_status argument to -l is a number specifying either a signal number or
    the exit status of a process terminated by a signal. The -L option is equiva‐
    lent to -l. kill returns true if at least one signal was successfully sent, or
    false if an error occurs or an invalid option is encountered.

    Al principio explican como bash protege los procesos, para evitar algunos problemas, pero no me queda claro cómo podría hacer un script seguro para correrlo como root.
    Lo único que se me ocurre es protegerlo así:

    $ cat killppid.sh
    #!/bin/bash
    if [ $USER == «root» ]
    then echo ¡¡¡No ejecute $0 como root!!! ¡es peligroso!
    exit
    fi

    kill -9 $(ps -eo pid,ppid | awk ‘$1==’${1}’ {print $2}’)

    $

    Usa el kill de bash, no /bin/kill

    Cómo se puede ver yo no soy muy versado en bash.
    ¿Saben ustedes cómo escribir un script seguro que corra como el usuario del proceso hijo, aunque se corra como root?
    algo equivalente a lo que manualmente se haría así:

    $ su ;
    $ kill -9 $(ps -eo pid,ppid | awk ‘$1==’${1}’ {print $2}’)