Objetivo:
Aprender a programar y automatizar la ejecución periódica de tareas y scripts de mantenimiento en sistemas operativos Linux, utilizando tanto el clásico planificador cron (crontab) como el moderno sistema de temporizadores de systemd (systemd timers).
Escenario:
- Herramientas: Terminal Linux,
crontab, demoniocron, unidades de systemd (.servicey.timer), editor de texto (Nano). - Conceptos analizados: Planificación temporal de tareas, sintaxis de expresiones cron (minutos, horas, días), gestión de registros de ejecución, persistencia ante reinicios y ventajas de systemd timers frente al cron tradicional.
- Proceso clave: Creación y edición de tareas programadas de usuario y del sistema, configuración de scripts de respaldo o mantenimiento periódico, y diseño de temporizadores avanzados basados en systemd.
Escenario Real: Automatizar las copias de seguridad nocturnas
Un servidor en producción necesita realizar una copia de seguridad comprimida de las bases de datos y carpetas críticas todas las madrugadas a las 03:30 AM, asegurando que el proceso se ejecute de manera desatendida y que cualquier error quede registrado en los logs del sistema. Como administrador, debes configurar un planificador de tareas fiable que garantice la ejecución periódica sin intervención humana, con capacidad de recuperación si el servidor estaba apagado en el momento previsto.
crontab). Sin embargo, en los sistemas operativos modernos basados en systemd, los **systemd timers** se han consolidado como una alternativa superior y más robusta, permitiendo gestionar dependencias complejas, control de registros integrado mediante el diario (journald) y la ejecución diferida de tareas si el equipo estaba apagado (persistent timers).NOTA: Esta práctica se realizará de forma controlada sobre nuestro entorno Linux de prácticas habitual, utilizando scripts sencillos de prueba para verificar la correcta planificación temporal.
Instrucciones:
Fase 1: Automatización mediante el planificador tradicional (Crontab):
- Comprobar el estado del servicio cron en el sistema para asegurar que está activo:
sudo systemctl status cron
- Abrir el editor del archivo crontab interactivo para el usuario actual:
crontab -e
- Añadir una tarea programada de prueba que escriba un mensaje en un archivo de texto cada minuto (útil para comprobar la ejecución rápida):
* * * * * echo "Prueba de cron ejecutada a las $(date)" >> /home/tu_usuario/cron_test.log
- Guardar y cerrar el archivo. El sistema indicará que se ha instalado un nuevo crontab.
Fase 2: Análisis de la sintaxis y patrones de tiempo en Cron:
- La sintaxis de crontab se compone de 5 campos temporales seguidos del comando a ejecutar:
┌───────────── minuto (0 - 59) │ ┌───────────── hora (0 - 23) │ │ ┌───────────── día del mes (1 - 31) │ │ │ ┌───────────── mes (1 - 12) │ │ │ │ ┌───────────── día de la semana (0 - 6, donde 0 es Domingo) │ │ │ │ │ * * * * * comando_a_ejecutar
- Para listar las tareas programadas actualmente asignadas a tu usuario:
crontab -l
- Para eliminar por completo todas las tareas programadas del usuario (útil para limpiar al finalizar pruebas):
crontab -r
Fase 3: Configuración avanzada mediante Systemd Timers:
- A diferencia de cron, systemd utiliza dos archivos vinculados: una unidad de servicio (
.service) que define qué se va a ejecutar, y una unidad de temporizador (.timer) que define cuándo se va a ejecutar. - Crear un archivo de servicio en el directorio de usuario o del sistema (ej.
/etc/systemd/system/backup-diario.service):[Service] Type=oneshot ExecStart=/usr/bin/tar -czf /tmp/backup_prueba.tar.gz /home/tu_usuario/proyectos_fp
- Crear el temporizador asociado (
/etc/systemd/system/backup-diario.timer) especificando el intervalo o la hora exacta:[Timer] OnCalendar=*-*-* 03:30:00 Persistent=true [Install] WantedBy=timers.target
Persistent=true en los systemd timers es una ventaja crítica frente a cron: si el servidor estaba apagado a las 03:30 AM, systemd ejecutará la tarea de forma automática en cuanto la máquina vuelva a encenderse, evitando perder el mantenimiento programado.Fase 4: Activación y monitorización de Timers:
- Recargar el demonio de systemd para que detecte las nuevas unidades creadas:
sudo systemctl daemon-reload
- Habilitar y arrancar el temporizador para que comience a monitorizar el tiempo:
sudo systemctl enable --now backup-diario.timer
- Comprobar el estado y la próxima fecha/hora programada de ejecución de todos los temporizadores activos en el sistema:
systemctl list-timers
Verificación:
- Comprobar el registro de ejecución de las tareas de cron observando el archivo de salida generado (
cat /home/tu_usuario/cron_test.log). - Inspeccionar el registro detallado en el diario de systemd para verificar los eventos del temporizador avanzado:
sudo journalctl -u backup-diario.timer
Posibles errores y resolución de problemas:
Si al programar una tarea en crontab el comando funciona perfectamente cuando lo ejecutas de forma manual en la terminal pero la tarea programada nunca genera ningún resultado ni error visible, suele deberse a que el entorno de ejecución de cron carece de las variables PATH completas o estás utilizando rutas relativas en lugar de rutas absolutas.
Solución: Especifica siempre las rutas absolutas completas de los comandos dentro de crontab (ej.
/usr/bin/python3en lugar depython3) o define la variablePATHal principio del archivo crontab.
Preguntas de reflexión:
- ¿Qué ventajas operativas aportan los
systemd timersfrente al planificador tradicionalcronen términos de control de dependencias y persistencia ante apagados del sistema? - ¿Por qué es un error crítico utilizar rutas relativas (ej.
script.sh) en lugar de rutas absolutas (ej./home/usuario/script.sh) al programar tareas automatizadas? - ¿Qué función cumple exactamente la directiva
Type=oneshoten una unidad de servicio de systemd diseñada para ser ejecutada por un temporizador? - ¿Qué implicaciones de seguridad y permisos tiene configurar tareas programadas mediante el archivo
crontabde root frente a crontabs de usuarios sin privilegios?
Haz clic aquí para ver las soluciones y explicaciones
1. ¿Qué ventajas operativas aportan los systemd timers frente al planificador tradicional cron en términos de control de dependencias y persistencia ante apagados del sistema?
Los systemd timers permiten definir dependencias estrictas (haciendo que un servicio se ejecute solo cuando la red, bases de datos u otros servicios estén completamente operativos), integran de manera nativa los registros en el journal centralizado, y soportan la opción Persistent=true, ejecutando automáticamente las tareas pendientes si el equipo estaba apagado en el momento previsto (algo que cron clásico por defecto no hace).
2. ¿Por qué es un error crítico utilizar rutas relativas (ej. script.sh) en lugar de rutas absolutas (ej. /home/usuario/script.sh) al programar tareas automatizadas?
Porque el demonio que ejecuta las tareas programadas (cron o systemd) opera con un entorno de shell mínimo y un directorio de trabajo predeterminado (generalmente el directorio raíz del usuario o de ejecución del sistema). Si usas rutas relativas, el sistema no sabrá en qué carpeta buscar el archivo, provocando el fallo inmediato de la tarea.
3. ¿Qué función cumple exactamente la directiva Type=oneshot en una unidad de servicio de systemd diseñada para ser ejecutada por un temporizador?
Indica a systemd que el servicio ejecuta una tarea puntual de tipo transitorio (realiza una acción y finaliza), a diferencia de los servicios estándar de red (*daemons*) que se mantienen permanentemente en ejecución escuchando peticiones en segundo plano.
4. ¿Qué implicaciones de seguridad y permisos tiene configurar tareas programadas mediante el archivo crontab de root frente a crontabs de usuarios sin privilegios?
Las tareas configuradas en el crontab de root se ejecutan con privilegios absolutos sobre todo el sistema operativo. Si un script automatizado por root contiene vulnerabilidades (como permisos de escritura inseguros en el archivo ejecutable), un usuario malintencionado podría modificarlo para elevar sus privilegios y comprometer todo el servidor. Por ello, las tareas deben ejecutarse siempre con el usuario con menor nivel de privilegios necesario.