Matar un proceso limpiamente

Matar un proceso limpiamente

Necesito hacer que la plataforma Linux Ubuntu inicie y finalice automáticamente un proceso, por ejemplo, si son las 8 a. m., el proceso comienza, si son las 7 p. m., el proceso finaliza, y eso tiene que ser todos los días, y debería estar bastante bien, si el intervalo de tiempo es ser fácil de cambiar.

Estoy intentando usar códigos simples en crontab:

28 12 * * * /home/pi/Desktop/start.sh
50 11 * * * pkill led.py

No mires las veces, intenté cambiarlas, start.shinicio led.pyel script, pero no puedo detenerlo si estoy usando pkill -9 -f led.py. El proceso finaliza, pero los LED no se apagan. Si inicio manualmente el programa y luego lo cierro con Ctrl+ c, los LED se apagan. ¿Dónde está el problema? ¿Por qué no puedo finalizar el proceso y al mismo tiempo apagar los LED?

Respuesta1

Cuando escribes Ctrl+ c, normalmente envía al proceso una señal "INT". Designal(7):

  Signal     Value     Action   Comment
  ──────────────────────────────────────────────────────────────────────
  ...
  SIGINT        2       Term    Interrupt from keyboard

Es común que los procesos instalen un controlador para esta señal, lo que les permite realizar una limpieza antes de salir. En el caso de su led.pyscript, parece que este controlador apagó los LED.

Por defecto, pkilly killenvía la señal "TERM" (15). (También intentaste enviar "KILL" (9).) Estas señales provocaron led.pyque muriera con menos gracia, sin tener la oportunidad de ejecutar su función de finalización.

Para permitir led.pyterminar limpiamente, se debe enviar la señal "INT" (2), con

pkill -2 [process specifier]

Es posible que el pkillcomando en su crontabtampoco haya podido encontrar el proceso, porque el nombre que proporcionó no era el que estaba buscando. Depkill(1):

-f, --completo

Elpatrónnormalmente solo se compara con el nombre del proceso. Cuando-Festá configurado, se utiliza la línea de comando completa.

Como su script, led.pypresumiblemente era un script de Python, el nombre del proceso era simplemente python(o python3, o similar). La línea de comando completa sería algo así como python led.py, por lo que las -fopciones te permiten coincidir con eso.

pkill -2 -f led.py

Respuesta2

Utilizo esta función desde hace muchos años:

function killit () {
for process in "$@"; do
    kill -0 $process &>/dev/null
    if [[ $? == 0 ]] ; then
        sudo kill $process #(sends a TERM, wait 5 seconds)
        sleep 5
        RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
        if [[ $RUNNING ]] ; then
            echo "$0 WARNING: process $process still running, trying kill again"
            sudo kill $process #(yes, try again, wait 5 seconds)
            sleep 5
            RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
            if [[ $RUNNING ]] ; then
                echo "$0 WARNING: process $process still running, trying kill -INT"
                sudo kill -INT $process  #(wait for it)
                sleep 5
                RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                if [[ $RUNNING ]] ; then
                    echo "$0 WARNING: process $process still running, trying kill -INT again"
                    sudo kill -INT $process  #(damn, still not dead?)
                    sleep 5
                    RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                    if [[ $RUNNING ]] ; then
                        echo "$0 WARNING: process $process still running, trying kill -KILL"
                        sudo kill -KILL $process #(same thing as -9)
                        sleep 5
                        RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                        if [[ $RUNNING ]] ; then
                            echo "$0 WARNING: process $process still running, trying kill -KILL again"
                            sudo kill -KILL $process #(something is wrong)
                            sleep 5
                            RUNNING=$(ps aux | tr -s " " "\t" | cut -f 2 | grep $process)
                            if [[ $RUNNING ]] ; then
                                echo "$0 WARNING: Can't kill process $process"
                                logger "$0 WARNING: Can't kill process $process"
                            fi
                        fi
                    fi
                fi
            fi
        fi
    fi
done
}

información relacionada