2009-08-04 24 views
7

¡Buen día! ¿Hay alguna forma de incluir un temporizador (marca de tiempo? O el término que sea) en una secuencia de comandos usando bash? Como por ejemplo; cada 60 segundos, una función específica comprueba si Internet no funciona, si es así, se conecta al dispositivo wifi y viceversa. En resumen, el programa verifica la conexión a Internet de vez en cuando.¿Cómo incluir un temporizador en Bash Scripting?

Cualquier sugerencia/respuesta será muy apreciada. =)

Respuesta

18

Blunt versión

while sleep 60; do 
    if ! check_internet; then 
    if is_wifi; then 
     set_wired 
    else 
     set_wifi 
    fi 
    fi 
done 

Utilizando el sueño como condición de bucle le permite salir del bucle matando al sueño (es decir, si se trata de un proceso en primer plano, Ctrl-C va a hacer).

Si hablamos de minutos o intervalos de horas, cron probablemente hará un mejor trabajo, como señaló Montecristo.

+0

Ya veo .. Voy a probar este. ¡Gracias chicos! Será mejor que le lea sobre "hombre cron" también. =) – Suezy

+0

llamadas de función no deberían tener parens al final. – camh

+0

absolutamente correcto, solo la declaración debería, cambiaré eso ... – falstro

5

Es posible que desee hacer un hombre cron.

O si lo que tiene que atenerse a golpear sólo hay que poner la llamada de función dentro de un bucle y sueño 60 dentro de la iteración.

0

Cree una secuencia de comandos bash que comprueba una vez si la conexión a Internet está inactiva y agregue la secuencia de comandos en una tarea de crontab que se ejecuta cada 60 segundos.

4

Encuentre aquí una secuencia de comandos que se pueden utilizar, primero agregar una entrada a su tarea en el cron como esto:

$ sudo crontab -e * * * * */ruta/a/su/selector de

Este es un método simple que reside en hacer ping continuamente a un servidor vivo cada minuto, si el servidor no es accesible, cambiará al segundo enrutador definido más abajo.

seguramente hay una mejor manera de explotar este problema.

$ cat> conmutador

#!/bin/sh 

route=`which route` 
ip=`which ip` 

# define your email here 
mail="[email protected]" 

# We define our pingable target like 'yahoo' or whatever, note that the host have to be 
# reachable every time 
target="www.yahoo.com" 

# log file 
file="/var/log/updown.log" 

# your routers here 
router1="192.168.0.1" 
router2="192.168.0.254" 

# default router 
default=$($ip route | awk '/default/ { print $3 }') 

# ping command 
ping -c 2 ${target} 

if [ $? -eq 0 ]; then 
    echo "`date +%Y%m%d-%H:%M:%S`: up" >> ${file} 

else 
    echo "`date +%Y%m%d-%H:%M:%S`: down" >> ${file} 

    if [ ${default}==${router1} ]; then 
     ${route} del default gw ${router1} 
     ${route} add default gw ${router2} 
    elif [ ${default}==${router2} ]; then 
     ${route} del default gw ${router2} 
     ${route} add default gw ${router1} 
    fi 
    # sending a notification by mail or may be by sms 
    echo "Connection problem" |mail -s "Changing Routing table" ${mail} 
fi 
+1

error tipográfico anterior - debe ser "sudo crontab -e ..." no "sudo contab -e ..." –

+0

Parece la mejor solución como cron está diseñado para este tipo de tarea.Haga algo (es decir, una secuencia de comandos) sobre un retraso de tiempo repetible. – Jim

+0

Creo que el script falla para detectar automáticamente el enrutador predeterminado, pero creo que lo encontré –

1

se puede hacer algo como lo siguiente, pero no es fiable:

 
#!/bin/sh 

trap handle_timer USR1 

set_timer() { (sleep 2; kill -USR1 $$)& } 
handle_timer() { 
    printf "%s:%s\n" "timer expired" "$(date)"; 
    set_timer 
} 

set_timer 
while true; do sleep 1; date; done 

Un problema con esta técnica es que la trampa no tendrá efecto hasta la tarea actual regresa al shell (p. ej., reemplaza el sleep 1 con el sleep 10). Si el caparazón tiene el control la mayor parte del tiempo (por ejemplo, si todos los comandos que llama terminan rápidamente), esto puede funcionar. Una opción, por supuesto, es ejecutar todo en segundo plano.

3

Me gustó la respuesta de William, porque no necesita votación. Así que implementé el siguiente script basado en su idea. Funciona alrededor del problema que el control tiene que devolver al shell.

#!/bin/sh 

someproc() 
{ 
     sleep $1 
     return $2 
} 

run_or_timeout() 
{ 
     timeout=$1 
     shift 

     { 
       trap 'exit 0' 15 
       "[email protected]" 
     } & 
     proc=$! 

     trap "kill $proc" ALRM 
     { 
       trap 'exit 0' 15 
       sleep $timeout 
       kill -ALRM $$ 
     } & 
     alarm=$! 

     wait $proc 
     ret=$? 

     # cleanup 
     kill $alarm 
     trap - ALRM 
     return $ret 
} 

run_or_timeout 0 someproc 1 0 
echo "exit: $? (expected: 142)" 
run_or_timeout 1 someproc 0 0 
echo "exit: $? (expected: 0)" 
run_or_timeout 1 someproc 0 1 
echo "exit: $? (expected: 1)"