Coffee bytes

Apuntes de desarrollo web con GNU/Linux, Python y Javascript

Programa tus tareas periódicas con Cron y Crontab en GNU/Linux

El sábado, 1 de febrero de 2020

por Eduardo Zepeda

Tiempo de lectura: 5 minutos

Muchas veces queremos ejecutar un script o un comando cada cierto tiempo, por ejemplo cuando queremos realizar backups periódicos de una base de datos, enviar a tus suscriptores un correo electrónico de recordatorio, o quizás eliminar archivos de cache cada cierta cantidad de tiempo.

Una manera bastante ingenua sería crear un script y utilizar el método time.sleep() de Python, o su equivalente en otro lenguaje, para retrasar su ejecución por el tiempo deseado. Sin embargo no necesitamos reinventar la rueda; alguien ya se encargó de esta tarea en GNU/Linux.

El daemon cron y comandos básicos

Cron es un daemon, disponible en muchas distribuciones de GNU/Linux, que lee un archivo localizado en la ruta /var/spool/cron/crontabs/tu_usuario y ejecuta las tareas que estén especificadas ahí, siempre y cuando su horario especificado de ejecución sea el adecuado.

Para revisar el contenido del archivo que será revisado por el daemon Cron usaremos el comando crontab con la opción -l a continuación

crontab -l

Este archivo no debe editarse directamente, la manera correcta de modificarlo es ejecutando el comando crontab, seguido de la opción -e

crontab -e

Esto nos abrirá nuestro editor de texto de consola predeterminado. Al revisar el contenido veremos que la mayoría del texto está comentado. Justo al final del archivo podremos encontrar estas lineas, las cuales nos especifican el formato que usaremos para programar nuestras tareas.

# m h  dom mon dow   command

El significado de cada elemento de esa linea es el siguiente:

  • # Sirve para mantener esta linea comentada, no lo remuevas.
  • m significa minutos (minutes)
  • h significa horas (hours)
  • dom significa día del mes (day of month)
  • mon significa mes (month)
  • dow significa día de la semana (day of week)
  • command significa comando

Para decirle a crontab como ejecutar una tarea llenaremos lineas en ese archivo siguiendo el patrón anterior. Por ejemplo:

# m h  dom mon dow   command
* * * * * script.py

Esta configuración ejecutaría el archivo script.py cada minuto, de cada hora, de cada día del mes, de cada mes, de cada día de la semana.

# m h  dom mon dow   command
0 6 * * * script.py

Por otro lado, la configuración anterior ejecutaría script.py cada día a las 6:00 a.m.

# m h  dom mon dow   command
0 6 * * 1 script.py

Esta de aquí ejecutará script.py cada lunes a las 6:00 a.m. Nota que crontab cuenta el domingo como el día 0 y también es el día 7, así mismo puedes usar las primeras tres letras en inglés de cada día, es decir, podemos reemplazar el 1 por ‘mon’, sin las comillas.

# m h  dom mon dow   command
0 6 30 * * script.py

Esta configuración ejecutará nuestro script el día 30 de cada mes a las 6:00 a.m.

# m h  dom mon dow   command
0 6 30 12 * script.py

Y por último esta configuración ejecutaría el comando el día 30 de diciembre a las 6:00 a.m.

¿Confundido? Es normal, yo creo que toma un poco de tiempo. De cualquier manera al final de esta entrada te comparto una herramienta genial para facilitarte el crear y entender estas configuraciones.

Algunos ejemplos más complejos

Quizás queremos algo más complejo que los ejemplos anteriores, ¿qué tal si tenemos un script que se encarga de pagarle a los empleados y queremos que se ejecute todos los días 1 y 15 de cada mes? En crontab podemos separar tantos valores como deseemos usando comas.

# m h  dom mon dow   command
0 9 1,15 * *  script.py

Y si queremos que un script que se ejecute cada hora, pero solo durante la madrugada de los sábados y domingos, desde las 12:00 a.m. hasta las 6:00 a.m. Crontab permite especificar rangos de valores usando guiones

# m h  dom mon dow   command
0 0-6 * * 6,7  script.py

¿Qué tal si nos gustaría cambiar de wallpaper cada 6 horas? No hay problema, podemos usar una diagonal en crontab para establecer periodos de tiempo.

# m h  dom mon dow   command
0 */6 * * *  script.py

Crontab y las variables de entorno

Hay algo muy importante que debemos recordar cada vez que utilicemos Crontab; las variables de entorno. Normalmente en un sistema GNU/Linux tenemos una serie de variables de entorno, las cuales podremos visualizar usando el comando printenv en consola. Intenta ejecutar el comando en tu consola para que veas la gran cantidad de variables de entorno que tiene tu sistema. Las variables de entorno pueden variar enormemente de acuerdo al usuario, pero lo importante es apreciar que son bastantes.

printenv
...
USER=usuario
DESKTOP_SESSION=default
QT_QPA_PLATFORMTHEME=qgnomeplatform
...

Por otro lado si tu obtienes las variables de entorno que están activas cuando usas Crontab podrás notar que son muchas menos. Crontab no tiene acceso a todas las variables de entorno.

PATH=/usr/bin:/bin
LANG=es_MX.UTF-8
HOME=/home/usuario
LANGUAGE=es_MX:es
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
SHELL=/bin/sh
LOGNAME=usuario
PWD=/home/usuario

¿Y esto porque es importante? Porque a veces programamos tareas que requieren de variables de entorno para poder ejecutarse correctamente y, si Crontab no puede acceder a ellas, pues fallará al ejecutarlas. Una vez más, recuerda que crontab no tiene acceso a todas las variables de entorno.

Una herramienta bastante útil

Como ya te has dado cuenta a veces la configuración puede complicarse demasiado y si no lo hacemos bien puede haber consecuencias; sencillas, como que nuestro script cambie de wallpaper cada minuto en lugar de cada hora; o graves, como que nuestro respaldo no se efectúe con la periodicidad deseada. Imagínate que, sin desearlo, programaste el respaldo de la base de datos una vez cada año en lugar de una vez cada veinticuatro horas, vas a pasar un mal rato si la base de datos llega a fallar.

Para evitarnos disgustos existe una herramienta bastante útil llamada crontab.guru. Esta herramienta se encargará de traducir tu configuración a simple y sencillo inglés, fácil de entender. Si tienes dudas sobre si la configuración que acabas de escribir es realmente la correcta, puedes teclearla en la página web y te mostrará el resultado en inglés.

¿Quieres aprender más?

Sígueme en Twitter y te aviso cuando tenga nuevo contenido disponible. ¡Es gratis!

¿Te pareció útil esta información?

Recibe más contenido como este en tu correo electrónico. Suscríbete, te toma unos segundos, es gratis, y puedes cancelar cuando quieras

* Campo obligatorio