Banda Ancha EU

Comunidad de usuarios
de fibra, móvil y ADSL

Programar/cronificar una tarea cada 10s

vukits

Introducción

Hay varias maneras de programar una tarea con cron1. Sobre todo en sistemas embebidos, esto puede cambiar de un sistema a otro… Asi que en este tutorial no se va a tratar el manejo especifico de crontab.

Problemática

Un defecto tienen en común: La granularidad de la programación es del orden de un minutos.

En mi caso, he querido ejecutar el script cada 10s. I.e. en segundos 0, 10, 20, 30, 40, 50.

Solución Propuesta

Esqueleto

Creamos nuestro script, que se llama 'patata.sh' (el que se ejecuta en el segundo 0)

Ahora… es aquí dónde está la triquiñuela… Preferentemente, en la misma carpeta que 'patata.sh' creo cinco otros ficheros que se llamarán 'patata10.sh', 'patata20.sh', 'patata30.sh', 'patata40.sh', 'patata50.sh' .

En mi caso, mi crontab contiene por lo menos esto (es muy dependiente del S.O. donde ejecutamos):

* * * * * ruta-de-script-original/patata.sh
* * * * * ruta-de-script-original/patata10.sh
* * * * * ruta-de-script-original/patata20.sh
* * * * * ruta-de-script-original/patata30.sh
* * * * * ruta-de-script-original/patata40.sh
* * * * * ruta-de-script-original/patata50.sh

Aunque, para el tema de cron, siempre hay soluciones más elegantes:

*/1 * * * * bash mitarea.sh
*/1 * * * * sleep 10 && bash mitarea.sh
*/1 * * * * sleep 20 && bash mitarea.sh
*/1 * * * * sleep 30 && bash mitarea.sh
*/1 * * * * sleep 40 && bash mitarea.sh
*/1 * * * * sleep 50 && bash mitarea.sh

Contenido de script principal

El contenido de 'patata.sh': (Realmente , podemos poner lo que queramos… en mi caso es un 'watchdog' que apaga el NAS si se va la luz (excepto entre 1:20 y 1:40).

tries=0
while [[ $tries -lt 1 ]]
do
    if /bin/ping -c 1 192.168.1.1 >/dev/null
    then
        exit 0
    fi
    tries=$((tries+1))
done

time=$(date +%k%M)
if [[ "$time" -ge 120 ]] && [[ "$time" -le 140 ]];then
    exit 0
else
    /usr/sbin/poweroff
fi

Contenido de scripts auxiliares de tiempo

El contenido de cada fichero 'patata n.sh', tiene dos variables, una es 'ruta-de-script-original' , la otra es 'n'. 'n' es '10' para 'patata10.sh", 20 para 'patata20.sh' , etc

#!/bin/sh
sleep n
'ruta-de-script-original'/patata.sh

Conclusión

No es una solución perfecta, ya que sleep puede tardar más o menos. Creo que se puede mejorar con temporizadores de kernel, pero a mi me sirve perfectamente…

Eso significa que si queremos ejecutar algo cada 30s, o cada 10s p.e., nos vamos a tener que apañar algo

  1. Programar en crontab
  2. Fuente2
  3. Alt-F Firmware
  4. Check time
BocaDePez
BocaDePez
1

Yo hacía algo más sencillo:

*/1 * * * * bash mitarea.sh
*/1 * * * * sleep 10 && bash mitarea.sh
*/1 * * * * sleep 20 && bash mitarea.sh
*/1 * * * * sleep 30 && bash mitarea.sh
*/1 * * * * sleep 40 && bash mitarea.sh
*/1 * * * * sleep 50 && bash mitarea.sh
🗨️ 3
vukits

EDIT: voy a poner tu versión, jeje

cierto, cierto…

es que mi NAS no soportaba lo de */1 … de hecho ni siquiera tiene crontab editable…

por eso dejé la edición de crontab aparte, porque en sistemas embebeidos, cada uno es de su padre y de su madre

🗨️ 1
BocaDePez
BocaDePez

Cierto. Lo mío es una respuesta general. En sistemas embebidos tienes que tratar con busybox, etc. y es un poco "sálvase quien pueda" :-) La mitad de funcionalidades no están, y la otra mitad están implementadas a medias.

campi

Más elegante, sin duda.

BocaDePez
BocaDePez

¿No aguanta 1 min el SAI?

🗨️ 1
vukits

no.

y no es por la bateria. que la cambié.

tiene un temporizador que apaga a los 45

rbetancor

Cron no se diseño para esa granularidad … así de simple.

Si necesitas algo de ese estilo, lo suyo es que desarrolles un demonio que te haga el sleep de forma nativa en su bucle principal.

También puedes optar por usar los timers de systemd