Terminando un bucle infinito

Terminando un bucle infinito

Tengo un comando que quiero que se ejecute nuevamente automáticamente cada vez que finalice, así que ejecuté algo como esto:

while [ 1 ]; do COMMAND; done;

pero si no puedo detener el ciclo, Ctrl-ceso simplemente mata COMMANDy no todo el ciclo.

¿Cómo podría lograr algo similar pero que pueda detener sin tener que cerrar la terminal?

Respuesta1

Puede detener y poner su trabajo en segundo plano mientras se ejecuta usando ctrl+ z. Entonces puedes acabar con tu trabajo con:

$ kill %1

Donde [1] es su número de trabajo.

Respuesta2

Verifique el estado de salida del comando. Si el comando fue terminado por una señal, el código de salida será 128 + el número de señal. Desde elDocumentación en línea de GNU para bash:

Para los propósitos del shell, un comando que sale con un estado de salida cero ha tenido éxito. Un estado de salida distinto de cero indica un error. Este esquema aparentemente contrario a la intuición se utiliza para que haya una forma bien definida de indicar el éxito y una variedad de formas de indicar varios modos de falla. Cuando un comando termina con una señal fatal cuyo número es N, Bash usa el valor 128+N como estado de salida.

POSIX también especificaque el valor de un comando que terminó con una señal es mayor que 128, pero no parece especificar su valor exacto como lo hace GNU:

El estado de salida de un comando que terminó porque recibió una señal se informará como mayor que 128.

Por ejemplo, si interrumpes un comando con control-C, el código de salida será 130, porque SIGINT es la señal 2 en los sistemas Unix. Entonces:

while [ 1 ]; do COMMAND; test $? -gt 128 && break; done

Respuesta3

Yo diría que sería mejor poner su bucle infinito en un script y manejar las señales allí. Aquí está unpunto de partida básico. Estoy seguro de que querrás modificarlo para adaptarlo. El script utiliza trappara capturar ctrl- c(o SIGTERM), finaliza el comando (lo he usado sleepaquí como prueba) y sale.

cleanup ()
{
kill -s SIGTERM $!
exit 0
}

trap cleanup SIGINT SIGTERM

while [ 1 ]
do
    sleep 60 &
    wait $!
done

Respuesta4

Si ejecuta bash con -eél, saldrá ante cualquier condición de error:

#!/bin/bash -e
false # returns 1
echo This won't be printed

información relacionada