¿Cómo enviar SIGKILL a todo el proceso?

¿Cómo enviar SIGKILL a todo el proceso?
while true; do 
    # process substitution instead of usual pipeline to avoid waiting for all programs
    handle_input_with_timeout < <( prog1 | prog2 | prog3 )
    echo "Data stopped flowing. Trying again"
    # perminate stuck programs in previous pipeline, then try again
    sleep 5
done

¿Cómo deshacerse de manera confiable de prog1, prog2 y prog3 que pueden quedarse atascados y retener los recursos necesarios para volver a intentarlo?

¿Se puede hacer solo en Bash o necesito usar cgroups?

Respuesta1

Esto se puede hacer con grupos de procesos (sugeridoaquí) y setsidpara empezar uno nuevo:

while true; do 

    handle_input_with_timeout < <( setsid bash -c '
          printf -- "-$$" > /tmp/saved_process_group.pid
          prog1 | prog2 | prog3
          ')
    echo "Data stopped flowing. Trying again"
    kill -9 $(< /tmp/saved_process_group.pid )

    sleep 5
done

Respuesta2

Puedes utilizar timeoutincluir en GNU's coreutils:

timeout <time in second> bash -c "prog1 | prog2 | prog3"

Ejemplo:

timeout 5 bash -c "pwd | sleep 10"

Utilice timepara asegurarse de que funcione:

$ time timeout 5 bash -c "pwd | sleep 10"

real    0m5.003s
user    0m0.000s
sys     0m0.000s

Respuesta3

Una técnica para controlar una tubería errónea es contar la cantidad de procesos de la tubería después de un tiempo. Si no han terminado, elimínelos y reinicie.

En este código de ejemplo usamos preguntarIntentopara su identificación de proceso (la $$variable), luego usepgreppara encontrar todos los subprocesos del script. Es decir, pgrepnos dice todos los ID de los procesos de flujo de trabajo. Si hay alguno, entonces utilizamos el correspondiente.matarcomando para aplastarlos antes de reiniciar.

Además, utilizamos elfechacomando para generar un bonito archivo de registro, que muestra qué está haciendo el sistema y en qué momento.

fuente:https://github.com/shavenwarthog/johntellsall/tree/master/karma/kill-pipeline


#!/bin/bash

# pipeline.sh -- start workflow; restart if jammed

while true; do

    date '+%X workflow starting'
    (sleep 30; echo gin) &
    (sleep 30; echo tonic) &

    date '+%X waiting for workflow to complete'
    sleep 5

    # count number of child procs (ie: workflow procs)
    # If there are any, kill them then restart.
    if pgrep -cP $$ > /dev/null ; then 
        date '+%X workflow jammed -- restarting; trying again'
        pkill -P $$
        sleep 2
        continue
    fi

    date '+%X workflow done!'
    break

done

Prueba de funcionamiento:

iniciar script de control de flujo de trabajo

$ ./pipeline.sh &

[1] 21291

02:06:39 PM workflow starting

02:06:39 PM waiting for workflow to complete

Los scripts de canalización esperan unos segundos, pero los procesos de flujo de trabajo aún se están ejecutando, ya que comienzan con un "suspensión 30".

Pipeline detecta que el flujo de trabajo está bloqueado, se queja y lo elimina antes de reiniciar.

02:06:44 PM workflow jammed -- restarting; trying again

./pipeline.sh: line 27: 21293 Terminated ( sleep 30; echo gin )

./pipeline.sh: line 27: 21294 Terminated ( sleep 30; echo tonic )

02:06:46 PM workflow starting

02:06:46 PM waiting for workflow to complete

Pipeline ahora está esperando que se complete el flujo de trabajo. Aquí haremos trampa y completaremos manualmente la tubería matando a los trabajadores.

$ pkill -f sleep

./pipeline.sh: line 27: 21363 Terminated sleep 30

./pipeline.sh: line 27: 21365 Terminated sleep 5

./pipeline.sh: line 27: 21364 Terminated sleep 30

tonic

La secuencia de comandos de canalización ahora advierte que todos los trabajadores han terminado, por lo que la canalización finaliza. Emite un mensaje de registro final y luego sale.

02:07:16 PM workflow done!

[1]+ Done ./pipeline.sh

información relacionada