2012-06-26 14 views
7

Necesito ejecutar la aplicación en cada X segundos, así que, en lo que cron no funciona con los segundos de esta manera, escribí un script bash con ciclo infinito con X segundos para dormir en él.Cómo detener el bucle infinito en script bash con gracia?

Cuando tengo que detener manualmente la secuencia de comandos en ejecución, me gustaría hacerlo de forma correcta, deje que la aplicación complete el funcionamiento y simplemente no ingrese el ciclo para la próxima vez.

¿Tiene alguna idea de cómo se puede lograr esto? Pensé en pasar argumentos, pero no pude encontrar cómo pasar el argumento al script en ejecución.

Respuesta

22

Usted podría atrapar una señal, dicen SIGUSR1:

echo "My pid is: $$" 
finish=0 
trap 'finish=1' SIGUSR1 

while ((finish != 1)) 
do 
    stuff 
    sleep 42 
done 

Entonces, cuando se quiere salir del bucle en la próxima iteración:

kill -SIGUSR1 pid 

Dónde pid es el proceso de identificación de la guión. Si la señal se eleva durante el sueño, se activará (el sueño duerme hasta que se produzca alguna señal).

+0

Gracias :) esto funciona –

2

Puede pasar algunos argumentos por un archivo. En cada iteración, puede leer este archivo y ver si sus condiciones de funcionamiento han cambiado.

1

La siguiente estructura puede ser adecuada si tiene que hacer algo de limpieza de todos modos. Use kill como se muestra en la respuesta de cdarke.

#=============================================================== 
# FUNCTION DEFINITIONS 
#=============================================================== 
# . . . 

#=== FUNCTION ================================================ 
#   NAME: cleanup 
# DESCRIPTION: 
#=============================================================== 
cleanup() 
{ 
    # wait for active children, remove empty logfile, ..., exit 
    exit 0 
} # ---------- end of function cleanup ---------- 

#=============================================================== 
# TRAPS 
#=============================================================== 
trap cleanup SIGUSR1 

#=============================================================== 
# MAIN SCRIPT 
#=============================================================== 
echo -e "Script '$0'/PID ${$}" 

while : ; do        # infinite loop 
    # . . . 
    sleep 10 
done 
# . . . 

#=============================================================== 
# STATISTICS/CLEANUP 
#=============================================================== 
cleanup 
0

La solución trampa publicado anteriormente es bueno para los grandes bucles, pero engorroso para el caso común donde se acaba de bucle a través de una sola o unas pocas órdenes. En este caso recomiendo la siguiente solución:

while whatever; do 
    command || break 
done 

Esto salir del bucle si el comando tiene un código de salida distinto de cero, lo que va a pasar si se interrumpe. Por lo tanto, a menos que command maneje SIGINT, presionar ctrl-C detendrá el comando actual y saldrá del ciclo.

Editar: Después de leer su pregunta más de cerca, veo que desea que el comando actual continúe la ejecución. En ese caso, esta solución no se aplica.