cita

Man is least himself when he talks in his own person. Give him a mask, and he will tell you the truth.
Oscar Wilde

diumenge, 25 de febrer del 2018

Cómo programar tareas en Linux (cron)... y que funcionen

¿Necesito programar tareas?


Programar una tarea en Linux nos permite ejecutar un comando, programa o script en un momento determinado. Muy útil para backups y otras tareas repetitivas en la administración del equipo.
The Mutiliation of Uranus by Saturn, de Giorgio Vasari
The Mutiliation of Uranus by Saturn, de Giorgio Vasari


¿Qué es cron y crontab?


Cron es una utilidad de sistemas Unix y derivados para programar (temporizar) la ejecución de procesos en segundo plano.
El servicio cron comprueba a cada minuto (y no menos de un minuto) si existe alguna tarea para ejecutar. Una vez finalizada la tarea enviará un mail al usuario propietario si el servicio está habilitado y configurado correctamente.
Crontab permite modificar las tareas que cron ejecutará.

¿Cómo se configura cron en Linux?


Primero debemos comprobar que el servicio cron esté habilitado y ejecutándose en el sistema. El servicio se suele llamar crond (como la mayoría de demonios), aunque también puede venir como cron. $ service crond status$ service cron statuscron is not running ... failed!
Para arrancar el servicio (en caso que esté parado):
$ service cron startStarting periodic command sheduler: cron.
En distros basadas en Arch Linux no se incluye cron por defecto, hay que instalarlo y habilitarlo (cronie es una alternativa a cron):
$ pacman -S cronie$ systemctl enable cronie$ systemctl start cronie$ systemctl status cronie
Para ver si el servicio está funcionando podemos mostrar procesos en ejecución (y filtrar sólo cron):
$ top | grep cron669 root 20 2 29664 2564 2280 S 0.0 0.1 0:00.00 cron
$ ps aux | grep cronroot 669 0.0 0.1 29664 2564 ? Ss 17:28 0:00 /usr/bin/cron
La ruta del binario de cron la encontramos en:
/usr/sbin/cron
Ruta fichero de configuración para el daemon de cron:
/etc/init.d/cron/etc/rc.d/cron
El fichero de configuración de crontab también permite añadir tareas programadas (aunque se recomienda utilizar el comando crontab -e):
/etc/crontab

¿Cómo funciona la planificación del tiempo en cron (cron expressions)?

Esquema del formato para planificar tareas en cron

Las tareas deben seguir una estructura determinada, son 5 temporizadores (los asteriscos de la imagen anterior) y luego la tarea a ejecutar. Más adelante en éste artículo hay varios ejemplos prácticos de programación de tareas con algunas cron expressions habituales.

Sustituiremos los asteriscos por un número (normalmente) que hace referencia al minuto, hora o día de ejecución (según el rango de valores que aparecen en la tabla anterior):
m * * * * "tarea" -> ejecuta la tarea en el minuto concreto * h * * * "tarea" -> ejecuta la tarea en una hora determinada (primer minuto) * * dom * * "tarea" -> ejecuta la tarea en un día del mes * * * mon * "tarea" -> ejecuta la tarea en un mes (primer día del mes) * * * * dow "tarea" -> ejecuta la tarea el día de la semana seleccionado
Existen unos modificadores que nos permiten definir un rango mas dinámico y amplio que se pueden aplicar en cualquier posición de los temporizadores (para ejecutar la misma tarea dos o más veces):
*/2 * * * * -> cada 2 minutos* 12-15 * * * -> desde las 12:00h hasta las 15:59h del mediodía* * 5,10,15 * * -> el día 5, 10 y 15 de cada mes
Siempre toma como referencia la hora del equipo, no desde el momento de la ejecución o inicio del sistema. Es decir, si la tarea está programada cada 5 minutos, empezará en el minuto 05, 10, 15 y así.

Hay que tener en cuenta la hora local del equipo donde programamos las tareas, es posible que utilize una zona (huso) horaria distinta a la nuestra (en servidores remotos, por ejemplo).
Comprobamos la fecha, hora y zona horaria del equipo:
$ dateSat Feb 24 13:03:16 CET 2018
Otro comando que nos dice la zona horaria con mas detalles es timedatectl:
cat /etc/timezone
Con el comando tzselect podemos modificar la configuración de zona horaria del equipo.

Comandos de configuración para las tareas de cron


Editar la configuración y tareas de cron para el usuario actual (en éste fichero es donde pondremos las cron expressions):
$ crontab -e
Editar la configuración y tareas de cron para el "usuario":
$ crontab -eu usuario
En el fichero de configuración crontab, cada línea representa un trabajo distinto.
Cron se ejecuta desde la carpeta personal del usuario (/home/usuario) que ejecuta cron, si queremos evitar problemas podemos utilizar rutas absolutas (el usuario debe tener permisos de lectura).

Para poder ejecutar (llamar) un script desde cron, éste tiene que tener permisos de ejecución.
Si queremos ejecutar un script de bash como tarea de cron podemos llamarlo así (dentro del fichero crontab):
* * * * * /bin/bash /home/usuario/script.sh
Si queremos ejecutar un comando o script que requiere privilegios de administrador (root) será más fácil modificar el crontab como usuario root, cuando se ejecute la tarea no va a solicitar contraseña:
$ sudo crontab -e
Por ejemplo, si queremos apagar el equipo requiere privilegios, así que ejecutamos el crontab como root (superusuario), luego añadimos el comando para apagar el equipo "shutdown 0":
$ sudo crontab -e* * * * * shutdown 0
Para ejecutar un programa con interfaz gráfica (GUI) desde cron debemos realizar una llamada al monitor por donde queremos mostrarlo (recordad que cron ejecuta las tareas en segundo plano):
$ sudo crontab -e* * * * * DISPLAY=:0 /usr/bin/firefox
Con el siguiente comando veremos cómo se llama nuestra pantalla:
$ echo $DISPLAY:0
Para salir del fichero de configuración de cron (crontab) y utilizas el editor de texto GNU nano:
CTRL+O para guardar
CTRL+X para salir

¿Cómo comprobar si una tarea de cron se ha ejecutado?


Podemos añadir código en la tarea para que genere un fichero de texto con el resultado y/o errores de ejecución del comando, como por ejemplo:
* * * * * "tarea" && echo "Backup completado: $(date)" >> /tmp/backup.log
Si no queremos recibir correos electrónicos con el resultado de cada tarea completada y que tampoco registre los errores, añadiremos una redirección al final:
* * * * * "tarea" > /dev/null 2>&1
Si sólo queremos recibir el correo cuando la tarea devuelva un error:
* * * * * "tarea" 1>/dev/null
También podemos consultar los ficheros de registro del sistema (logs) de los últimos 30 minutos mostrando sólo los relacionados con el servicio cron;
$ journalctl --since '30 min ago' | grep cron
Ver los últimos cinco mensajes del sistema relacionados con cron (si no disponemos de journalctl);
$ grep cron /var/log/syslog | tail -5
Si no encontramos nada, puede que cron esté configurado para no generar logs de registro, compruébalo en éste fichero de configuración;
$ cat /etc/default/cron

Ejemplos prácticos de tareas programadas para cron


Hay que sustituir el texto "tarea" por el comando o ruta al script que queremos ejecutar.
Todos los lunes a las 09:00h de la mañana:
00 09 * * 1 "tarea"
Cada día a las 16:15h de la tarde
15 16 * * * "tarea"
Sólo entre semana (de lunes a viernes) a las 20:30h de la tarde:
30 20 * * 1-2 "tarea"
Sólo el fin de semana (sábado y domingo) a las 09:00h de la mañana:
00 09 * * 6-7 "tarea"
Sólo el primer día de cada mes a las 21:00h de la noche:
00 21 1 * * "tarea"
Cada cinco minutos:
*/5 * * * * "tarea"
Cada hora y media (90 minutos):
*/90 * * * * "tarea"
Sólo los miércoles y viernes, cada media hora (30 minutos) desde las 10:00h de la mañana hasta las 13:59h del mediodía, la última se ejecutaría a las 13:30h (no es estándar, puede no funcionar en todos los sistemas):
*/30 10-13 * * WED,FRI "tarea"

Enlaces para crear tus expresiones de cron de forma fácil (web - GUI)


Crontab Guru: crontab.guru
Crontab Generator: crontab-generator.org
Cron Expression Description: cronexpressiondescriptor.azurewebsites.net
Cron Makercronmaker.com

Enlaces y referencias


Cron  - ArchWiki
wiki.archlinux.org/index.php/Cron
CronHowto
help.ubuntu.com/community/CronHowto
Programar tareas en Linux
estrellateyarde.org/utilidades/programar-tareas-en-linux
Programar tareas en linux usando crontab
geekytheory.com/programar-tareas-en-linux-usando-crontab
Cómo utilizar Cron y Crontab en Linux para programar tareas
redeszone.net/2017/01/09/utilizar-cron-crontab-linux-programar-tareas/
Best practices for cron
endpoint.com/blog/2008/12/08/best-practices-for-cron
How to check if a cron job ran
bencane.com/2011/11/02/did-my-cronjob-run