miércoles, 4 de diciembre de 2019

Cron: ejecutar script el primer lunes de cada mes



Cómo hacer que un script se ejecute el primer lunes de cada mes en Linux.



Los que conozcáis cron sabréis que es una utilidad que sirve para ejecutar scripts (o comandos) de forma recurrente en entornos Linux. Cron permite elegir el minuto, hora, dia, mes y día de la semana en que ejecutar un script automáticamente.


Ejecutar script el día 1 de cada mes



Siguiendo lo mencionado anteriormente, para hacer que un script se ejecute automáticamente el dia 1 de cada mes a las 2:00 de la madrugada, debemos usar la siguiente sintaxis en crontab:

0 2 1 * * /ruta/script.sh


Ejecutar script el primer lunes de cada mes



Puede que nos interese ejecutar un script, ya no el día 1 de cada mes, sino el primer lunes de cada mes, de modo que al entrar a la oficina a las 8:00h podamos actuar dependiendo del resultado generado por el script. Y que sea crítico que se ejecute el lunes porque sí o sí estaremos a la mañana siguiente en el trabajo, cosa que no pasaría si el día 1 de ese mes fuese sábado (por ejemplo).

NOTA: sí, puede que haya lunes que sean festivos...

La forma en la que está diseñado cron no contempla este tipo de planificación, pero eso no significa que no se pueda llevar a cabo. Para conseguir que un script se ejecute el primer lunes de cada mes a las 2:00h (por ejemplo), podemos usar la siguiente parametrización en crontab:

0 2 1-7 * * [ "$(date '+\%u')" = "1" ] && /ruta/script.sh

Lo que estamos haciendo es ejecutar un script y luego otro. Recordemos que, en bash, el operando && indica "si se cumple la condición anterior, ejecuta el comando siguiente". Es decir, si el día de la semana equivale a 1 (lunes), ejecuta el script.

En el primer script, vemos cómo se escapa el caracter % con el uso de comillas simples y \. Esto es necesario, puesto que si no se escapa el caracter, el comando no se ejecuta en cron. Sin más.


Número vs Nombre



Se podría usar [ "$(date '+\%a')" = "Mon" ] para comprobar si el día es lunes, pero entonces el script solo funcionaría en sistemas con el locale inglés. Si nuestro sistema estuviera en español, necesitaríamos compararlo con "lun", si estuviera en francés, con "lundi", etc.

Para evitar problemas con el idioma del sistema operativo, considero que es mejor usar el número del día (%u) en vez de usar el nombre del día (%a), ya que los números son universales, cosa que nos permitirá pasar esta entrada cron de un sistema a otro sin importar los locales.


Alternativa



De forma alternativa, se podría ejecutar el script cada lunes y dentro del script en sí comprobar si ese lunes es el primero del mes actual. Si es el primer lunes, seguir con la ejecución, y sino, ejecutar un simple "exit" para salir del script. Pero considero que esta opción gasta más tiempo de procesador.


Conclusión



Aunque cron no esté diseñado explícitamente para permitirnos ejecutar un script el primer dia X de cada mes, hemos visto cómo podemos llevar a cabo esta tarea usando simples comandos de bash.
3

3 comentarios:

  1. No me funciono, por esa via, lo ha probado que le funcione??

    ResponderEliminar
    Respuestas
    1. Hola,

      Con esta opción debería de funcionarte:

      0 2 1-7 * * [ "$(date '+\%u')" = "1" ] && /ruta/script.sh

      Saludos

      Eliminar
  2. Hola !
    Esta configuración debe funcionar

    0 2 1-7 * 1 /ruta/script.sh

    ya que cron une las opciones con un and. Entonces debe ser lunes y la fecha 1 al 7. Es el primer lunes del mes.

    ResponderEliminar