Automatización de tareas con Cron en Linux: guía completa

📅 Actualizado en febrero 2026 ✍️ Ángel López 📊 Nivel: Intermedio ⏱️ 25 min de lectura

La automatización de tareas es una de las habilidades fundamentales de cualquier administrador de sistemas Linux. Gracias a herramientas como cron, anacron, at y los modernos systemd timers, puedes programar copias de seguridad, rotación de logs, actualizaciones del sistema, envío de informes y prácticamente cualquier tarea repetitiva para que se ejecute sin intervención humana. En esta guía aprenderás a dominar todas estas herramientas con ejemplos prácticos y profesionales.

⏰ Qué es Cron y por qué es esencial

Cron es un demonio (servicio en segundo plano) presente en prácticamente todas las distribuciones Unix y Linux. Su función es sencilla pero poderosa: ejecutar comandos o scripts de forma automática en momentos predefinidos — cada minuto, hora, día, semana o mes, o en cualquier combinación de estos intervalos.

El nombre «cron» proviene del griego chronos (χρόνος), que significa «tiempo». Es uno de los servicios más antiguos y fiables de Unix, presente desde la versión 7 de Unix en 1979. La implementación más extendida en Linux moderno es Vixie Cron, creada por Paul Vixie en 1987, que es la base de las versiones que incluyen Ubuntu, Debian, Fedora y la mayoría de distribuciones actuales.

Engranajes de reloj simbolizando la automatización y la precisión temporal del sistema cron en Linux
Cron funciona como un mecanismo de relojería preciso: ejecuta tareas de forma automática y puntual según la programación definida por el administrador. Foto: Pexels.

La automatización con cron es esencial en la administración profesional de sistemas por varias razones:

VentajaDescripciónEjemplo real
FiabilidadLas tareas se ejecutan siempre a la hora programada, sin olvidos humanosBackup diario a las 3:00 AM
EficienciaTareas pesadas se programan en horas de baja actividadRegenerar índices de BD a medianoche
ConsistenciaEl mismo proceso se ejecuta exactamente igual cada vezRotación de logs cada domingo
EscalabilidadUn administrador gestiona cientos de servidores con tareas automatizadasActualización de seguridad en flota
AuditoríaCada ejecución queda registrada en logs del sistemaHistórico de tareas en syslog
💡 ¿Sabías que...?
Los grandes proveedores cloud como AWS, Google Cloud y Azure ejecutan internamente millones de tareas cron cada día para mantener su infraestructura. Servicios como la limpieza de objetos expirados en S3, la rotación de certificados TLS o la generación de informes de facturación dependen de sistemas de programación de tareas herederos directos de cron.

🏗️ Arquitectura del sistema Cron

Para dominar cron es fundamental entender cómo se organiza internamente. El sistema se compone de varios elementos que interactúan entre sí:

El demonio crond

El demonio cron (también llamado crond) se inicia automáticamente con el sistema y permanece activo en segundo plano. Cada minuto, despierta y comprueba si alguna tarea debe ejecutarse en ese instante. Si encuentra una coincidencia, lanza el comando correspondiente en un nuevo proceso shell.

terminal — verificar estado de cron
# Comprobar si cron está activo (systemd) systemctl status cron ● cron.service - Regular background program processing daemon Loaded: loaded (/lib/systemd/system/cron.service; enabled) Active: active (running) since Mon 2026-02-27 08:00:01 CET # En distribuciones Red Hat / Fedora el servicio se llama crond systemctl status crond

Los archivos crontab

Cada usuario del sistema puede tener su propio archivo crontab (cron table), que se almacena en /var/spool/cron/crontabs/ (Debian/Ubuntu) o /var/spool/cron/ (Red Hat/Fedora). Estos archivos no se editan directamente sino a través del comando crontab.

Directorios del sistema

Además de los crontabs de usuario, el sistema mantiene una estructura de directorios predefinida:

RutaFunciónFrecuencia
/etc/crontabCrontab principal del sistema (incluye campo de usuario)Definida en cada línea
/etc/cron.d/Crontabs adicionales instalados por paquetes del sistemaDefinida en cada línea
/etc/cron.hourly/Scripts ejecutados cada horaCada hora
/etc/cron.daily/Scripts ejecutados una vez al díaDiariamente
/etc/cron.weekly/Scripts ejecutados una vez por semanaSemanalmente
/etc/cron.monthly/Scripts ejecutados una vez al mesMensualmente
✅ Consejo práctico
Si tu tarea se ejecuta cada hora, cada día, cada semana o cada mes, la forma más sencilla es colocar un script ejecutable en el directorio correspondiente (/etc/cron.daily/, etc.). No necesitas escribir sintaxis crontab: basta con que el archivo sea un script con permisos de ejecución.
Arquitectura del sistema Cron en Linux Arquitectura del sistema Cron ⏰ Demonio cron Comprueba cada minuto 📄 Crontabs de usuario /var/spool/cron/crontabs/ 📋 /etc/crontab Crontab del sistema 📁 /etc/cron.d/ Crontabs de paquetes Directorios de ejecución periódica 🕐 cron.hourly Cada hora 📅 cron.daily Cada día 📆 cron.weekly Cada semana 🗓️ cron.monthly Cada mes El demonio cron lee los archivos de configuración cada minuto. Los directorios periódicos son gestionados por anacron o run-parts.

📋 Sintaxis de crontab: los 5 campos

La sintaxis de crontab es uno de esos conocimientos que todo administrador Linux debe memorizar. Cada línea de un crontab de usuario sigue este formato:

formato crontab
# ┌───────────── minuto (0-59) # │ ┌─────────── hora (0-23) # │ │ ┌───────── día del mes (1-31) # │ │ │ ┌─────── mes (1-12 o jan-dec) # │ │ │ │ ┌───── día de la semana (0-7, 0 y 7 = domingo, o sun-sat) # │ │ │ │ │ # * * * * * comando_a_ejecutar

Descripción detallada de cada campo

CampoRangoValores especialesEjemplo
Minuto0–59*, */n, n-m, n,m30 = minuto 30
Hora0–23*, */n, n-m, n,m14 = 2:00 PM
Día del mes1–31*, */n, n-m, n,m1,15 = días 1 y 15
Mes1–12 (o jan–dec)*, */n, n-m, n,m6 = junio
Día de la semana0–7 (o sun–sat)*, */n, n-m, n,m1-5 = lunes a viernes

Operadores especiales

Los operadores permiten definir patrones complejos de ejecución sin necesidad de enumerar cada valor:

OperadorSignificadoEjemploResultado
*Cualquier valor* * * * *Cada minuto
,Lista de valores0,30 * * * *Minutos 0 y 30
-Rango de valores* 9-17 * * *De 9:00 a 17:59
/Paso (cada N)*/10 * * * *Cada 10 minutos
⚠️ Cuidado con la combinación día del mes + día de la semana
En cron estándar, si especificas AMBOS campos (día del mes y día de la semana), la tarea se ejecuta cuando se cumple cualquiera de los dos, no ambos simultáneamente. Por ejemplo, 0 8 15 * 1 se ejecuta los días 15 de cada mes Y también todos los lunes. Este comportamiento sorprende a muchos administradores.

Atajos especiales de crontab

Muchas implementaciones de cron aceptan cadenas especiales que simplifican la configuración:

AtajoEquivalenteSignificado
@reboot— (especial)Al arrancar el sistema
@yearly0 0 1 1 *Una vez al año (1 enero, medianoche)
@monthly0 0 1 * *Una vez al mes (día 1, medianoche)
@weekly0 0 * * 0Una vez por semana (domingo, medianoche)
@daily0 0 * * *Una vez al día (medianoche)
@hourly0 * * * *Una vez por hora (minuto 0)

🛠️ Gestión de crontab: crear, editar y listar

El comando crontab es la herramienta principal para gestionar las tareas programadas de un usuario. Nunca debes editar directamente los archivos en /var/spool/cron/; el comando crontab se encarga de validar la sintaxis y notificar al demonio cron de los cambios.

terminal — comandos crontab esenciales
# Editar tu crontab (abre el editor predeterminado) crontab -e # Listar las tareas programadas del usuario actual crontab -l # Eliminar TODAS las tareas del usuario actual (¡cuidado!) crontab -r # Pedir confirmación antes de eliminar crontab -ri # Como root: ver el crontab de otro usuario sudo crontab -l -u www-data # Como root: editar el crontab de otro usuario sudo crontab -e -u mysql
💡 Elegir tu editor
Si al ejecutar crontab -e se abre un editor que no te resulta familiar (como nano o vi), puedes cambiar el editor predeterminado con: export EDITOR=nano (o vim, code, etc.). Para hacerlo permanente, añade esa línea a tu ~/.bashrc.

Instalar un crontab desde archivo

Una práctica profesional es mantener tus crontabs en archivos de texto versionados con Git. Puedes instalar un crontab directamente desde un archivo:

terminal — crontab desde archivo
# Crear un archivo con tus tareas cat > mi_crontab.txt << 'EOF' # Backup diario a las 3:00 AM 0 3 * * * /home/admin/scripts/backup.sh # Limpieza de temporales cada domingo a las 4:00 AM 0 4 * * 0 /home/admin/scripts/limpiar_tmp.sh EOF # Instalar el archivo como tu crontab (REEMPLAZA el existente) crontab mi_crontab.txt # Verificar que se instaló correctamente crontab -l
⚠️ Precaución importante
El comando crontab archivo.txt reemplaza completamente tu crontab actual. No añade las líneas al final. Si quieres añadir tareas sin perder las existentes, exporta primero con crontab -l > mi_crontab.txt, edita el archivo y luego reinstala.

🎯 Ejemplos prácticos de tareas programadas

Veamos una colección de ejemplos reales que cubren los escenarios más comunes en la administración de sistemas:

Tareas de mantenimiento del sistema

crontab — mantenimiento
# Backup completo cada día a las 2:30 AM 30 2 * * * /usr/local/bin/backup_completo.sh >> /var/log/backup.log 2>&1 # Actualizar paquetes de seguridad cada noche a las 3:00 AM 0 3 * * * /usr/bin/apt-get update && /usr/bin/apt-get upgrade -y --security >> /var/log/apt-security.log 2>&1 # Limpiar archivos temporales mayores de 7 días cada domingo a las 4:00 AM 0 4 * * 0 /usr/bin/find /tmp -type f -mtime +7 -delete # Rotar logs personalizados el día 1 de cada mes 0 0 1 * * /usr/sbin/logrotate /etc/logrotate.d/mi_app

Tareas de monitorización

crontab — monitorización
# Comprobar uso de disco cada 6 horas 0 */6 * * * /usr/local/bin/check_disk.sh # Verificar que Apache está corriendo cada 5 minutos */5 * * * * /usr/bin/systemctl is-active apache2 || /usr/bin/systemctl restart apache2 # Enviar informe de rendimiento cada lunes a las 8:00 AM 0 8 * * 1 /usr/local/bin/informe_semanal.sh | /usr/bin/mail -s "Informe semanal" admin@empresa.com

Tareas de desarrollo y base de datos

crontab — desarrollo y BD
# Dump de MySQL cada noche a las 1:00 AM 0 1 * * * /usr/bin/mysqldump -u backup --all-databases | /usr/bin/gzip > /backups/mysql/db_$(date +\%Y\%m\%d).sql.gz # Pull del repositorio y deploy cada hora en horario laboral 0 9-18 * * 1-5 cd /var/www/mi_app && /usr/bin/git pull origin main && /usr/local/bin/deploy.sh # Generar sitemap XML cada día a las 5:00 AM 0 5 * * * /usr/bin/php /var/www/mi_app/generar_sitemap.php
✅ Buena práctica: escapar el signo %
En crontab, el signo % tiene un significado especial: se interpreta como salto de línea. Si necesitas usarlo (por ejemplo, con date +%Y%m%d), debes escaparlo con barra invertida: date +\%Y\%m\%d. Este es uno de los errores más frecuentes en tareas cron que nunca se ejecutan.
Flujo de trabajo de automatización en terminal Linux, representando scripts y tareas cron
La automatización mediante scripts y cron es el pilar de la administración profesional de sistemas: cada tarea repetitiva debe estar programada, documentada y monitorizada. Foto: Pexels.

🔧 Variables de entorno en crontab

Uno de los errores más comunes al trabajar con cron es asumir que las tareas se ejecutan con el mismo entorno que tu sesión de terminal. No es así. Cron ejecuta cada tarea con un entorno mínimo y restringido.

crontab — variables de entorno
# Variables que puedes definir en la cabecera de tu crontab SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin MAILTO=admin@empresa.com HOME=/home/admin # El PATH predeterminado de cron es MUY limitado: # PATH=/usr/bin:/bin (solo eso) # Por eso es CRÍTICO usar rutas absolutas o definir PATH # Ejemplo: sin PATH explícito, esto FALLA # 0 3 * * * mysqldump -u root mi_bd > /tmp/backup.sql # Correcto: ruta absoluta 0 3 * * * /usr/bin/mysqldump -u root mi_bd > /tmp/backup.sql
VariableValor por defecto en cronRecomendación
SHELL/bin/shDefinir /bin/bash si usas bashisms
PATH/usr/bin:/binDefinir PATH completo o usar rutas absolutas
HOMEHome del usuarioGeneralmente correcto, ajustar si es necesario
MAILTOUsuario propietario del crontabDefinir email o vacío para no enviar
LANGNo definidoDefinir si el script maneja texto con acentos
⚠️ La variable MAILTO
Si MAILTO no está definida (o está configurada con el valor por defecto), cron envía un email al usuario propietario del crontab con la salida de cada tarea. En servidores con muchas tareas esto puede generar miles de correos internos. Para silenciar una tarea concreta, redirige su salida: comando > /dev/null 2>&1. Para silenciar todas: MAILTO="".

📂 El crontab del sistema: /etc/crontab y cron.d

Además de los crontabs personales de cada usuario, existe un crontab del sistema en /etc/crontab. Este archivo tiene una diferencia crucial: incluye un campo adicional para especificar con qué usuario se ejecuta cada tarea.

/etc/crontab — crontab del sistema
# /etc/crontab: system-wide crontab SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow USUARIO comando 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

Observa la lógica: si anacron está instalado, las tareas diarias, semanales y mensuales las gestiona anacron (que garantiza su ejecución aunque el sistema se apague). Si anacron no está disponible, run-parts ejecuta los scripts directamente.

El directorio /etc/cron.d/

El directorio /etc/cron.d/ contiene archivos crontab adicionales, normalmente instalados por paquetes del sistema. Cada archivo sigue la misma sintaxis que /etc/crontab (con campo de usuario). Es la forma recomendada de añadir tareas de sistema sin modificar /etc/crontab directamente.

/etc/cron.d/certbot — ejemplo real
# /etc/cron.d/certbot: renovación automática de certificados Let's Encrypt # Ejecuta dos veces al día. No hace nada si no hay certificados por renovar. 0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew
💡 El truco del sleep aleatorio
Observa cómo Certbot incluye un sleep aleatorio antes de ejecutarse. Esto evita que miles de servidores renueven sus certificados simultáneamente, distribuyendo la carga sobre los servidores de Let's Encrypt. Es una buena práctica conocida como jitter (dispersión temporal).

🔄 Anacron: tareas para equipos que se apagan

Anacron resuelve una limitación fundamental de cron: si el equipo está apagado en el momento programado, cron simplemente no ejecuta la tarea y no hay recuperación. Anacron, en cambio, registra cuándo se ejecutó cada tarea por última vez y, al arrancar el sistema, ejecuta las tareas pendientes.

/etc/anacrontab
# /etc/anacrontab: configuración de anacron # formato: periodo retardo(min) id_tarea comando SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin HOME=/root LOGNAME=root # Estas tareas aseguran que cron.daily/weekly/monthly se ejecutan # aunque el equipo no estuviera encendido a la hora programada 1 5 cron.daily run-parts --report /etc/cron.daily 7 10 cron.weekly run-parts --report /etc/cron.weekly @monthly 15 cron.monthly run-parts --report /etc/cron.monthly

El campo de retardo es importante: indica cuántos minutos esperar después del arranque antes de ejecutar la tarea. Esto evita que todas las tareas pendientes se lancen simultáneamente al encender el equipo, lo que podría saturar los recursos.

CaracterísticaCronAnacron
PrecisiónAl minuto exactoSolo diario o superior
Si el equipo está apagadoPierde la tareaLa ejecuta al arrancar
Ejecución concurrentePuede ejecutar múltiples en paraleloSecuencial, una tras otra
Ideal paraServidores 24/7Portátiles y estaciones de trabajo
Demonio permanenteNo, se ejecuta una vez y termina

🎯 El comando at: ejecución única programada

Mientras cron es ideal para tareas recurrentes, el comando at sirve para programar la ejecución de un comando una única vez en un momento futuro específico.

terminal — comando at
# Instalar at (si no está disponible) sudo apt install at # Iniciar el servicio atd sudo systemctl enable --now atd # Programar un comando para las 3:00 PM de hoy echo "/usr/local/bin/mi_script.sh" | at 15:00 # Programar para mañana a las 10:00 AM echo "/usr/local/bin/informe.sh" | at 10:00 tomorrow # Programar para dentro de 2 horas echo "reboot" | sudo at now + 2 hours # Programar para una fecha específica echo "/usr/local/bin/generar_informe_trimestral.sh" | at 09:00 03/31/2026 # Modo interactivo (terminar con Ctrl+D) at 23:00 at> /usr/local/bin/limpieza_nocturna.sh at> echo "Limpieza completada" | mail admin@empresa.com at> <Ctrl+D> # Listar tareas pendientes atq # Eliminar una tarea pendiente (por número de trabajo) atrm 5
✅ Caso de uso perfecto para at
at es ideal para situaciones como: «Necesito reiniciar el servidor esta noche a las 3:00 AM después de aplicar un parche», o «Quiero enviar un recordatorio por email dentro de 4 horas». Cuando necesitas programar algo puntual sin modificar tu crontab.

⚡ Systemd timers: la alternativa moderna

En distribuciones modernas con systemd (Ubuntu 16.04+, Debian 8+, Fedora, CentOS 7+), existe una alternativa a cron cada vez más popular: los systemd timers. Son unidades systemd que activan otros servicios en momentos específicos.

¿Por qué considerar systemd timers?

VentajaCronSystemd timers
LogsEmail o redirección manualIntegrado en journalctl
DependenciasNo soportaAfter=, Requires=, etc.
Precisión1 minutoMicrosegundos
Ejecución perdidaSe pierde (sin anacron)Persistent=true
AleatorizaciónManual con sleepRandomizedDelaySec=
MonitorizaciónScripts personalizadossystemctl list-timers
ComplejidadUna líneaDos archivos (.service + .timer)

Crear un timer paso a paso

Un systemd timer requiere dos archivos: una unidad de servicio (.service) que define qué ejecutar, y una unidad de timer (.timer) que define cuándo ejecutarlo.

/etc/systemd/system/backup-diario.service
[Unit] Description=Backup diario del sistema After=network-online.target [Service] Type=oneshot ExecStart=/usr/local/bin/backup_completo.sh User=root StandardOutput=journal StandardError=journal
/etc/systemd/system/backup-diario.timer
[Unit] Description=Ejecutar backup diario a las 2:30 AM [Timer] OnCalendar=*-*-* 02:30:00 Persistent=true RandomizedDelaySec=300 [Install] WantedBy=timers.target
terminal — activar el timer
# Recargar configuración de systemd sudo systemctl daemon-reload # Activar el timer para que arranque con el sistema sudo systemctl enable backup-diario.timer # Iniciar el timer ahora sudo systemctl start backup-diario.timer # Verificar estado sudo systemctl status backup-diario.timer # Listar todos los timers activos systemctl list-timers --all # Ver logs de la última ejecución journalctl -u backup-diario.service --since today
Flujo de decisión: ¿Cron o Systemd Timer? ¿Cron o Systemd Timer? ¿Necesitas logs, dependencias o persistencia? No ⏰ Usa Cron Simple, una línea Universal, probado ⚡ Usa Timer Logs en journalctl Dependencias + persistencia 💡 Ambos son válidos. Elige según la complejidad del caso.

🔒 Seguridad y control de acceso en Cron

Cron implementa un sistema de control de acceso basado en dos archivos: /etc/cron.allow y /etc/cron.deny. Estos archivos determinan qué usuarios pueden utilizar el comando crontab.

Escenariocron.allowcron.denyResultado
Existe cron.allowUsuario listadoSe ignoraPuede usar cron
Existe cron.allowUsuario NO listadoSe ignoraNo puede usar cron
No existe cron.allowUsuario listadoNo puede usar cron
No existe cron.allowUsuario NO listadoPuede usar cron
No existe ningunoSolo root (Debian) / Todos (Red Hat)
terminal — control de acceso cron
# Permitir solo a usuarios específicos usar cron sudo bash -c 'echo "admin" > /etc/cron.allow' sudo bash -c 'echo "deploy" >> /etc/cron.allow' # Alternativa: permitir a todos excepto algunos sudo bash -c 'echo "invitado" > /etc/cron.deny' sudo bash -c 'echo "temporal" >> /etc/cron.deny' # Lo mismo aplica para at: /etc/at.allow y /etc/at.deny
⚠️ Seguridad: revisa los crontabs periódicamente
En entornos de producción, revisa regularmente los crontabs de todos los usuarios con for user in $(cut -f1 -d: /etc/passwd); do echo "=== $user ==="; crontab -l -u $user 2>/dev/null; done. Un atacante que obtenga acceso limitado podría añadir tareas cron para mantener persistencia en el sistema.

🔍 Depuración y solución de problemas

Cuando una tarea cron no funciona como esperas, sigue esta metodología de diagnóstico:

1. Verificar que cron está activo

terminal — diagnóstico cron
# ¿Está corriendo el demonio cron? systemctl status cron # Si no está activo: sudo systemctl start cron sudo systemctl enable cron

2. Revisar los logs

terminal — logs de cron
# Ver las últimas entradas de cron en el log grep CRON /var/log/syslog | tail -20 # En Red Hat / Fedora: grep CRON /var/log/cron | tail -20 # Con journalctl (systemd): journalctl -u cron --since "1 hour ago" # Monitorizar en tiempo real: tail -f /var/log/syslog | grep CRON

3. Probar el script manualmente

terminal — probar script
# Ejecutar el script con el mismo entorno que usaría cron env -i SHELL=/bin/sh PATH=/usr/bin:/bin HOME=/root /ruta/al/script.sh # Verificar permisos de ejecución ls -la /ruta/al/script.sh # Si falta +x: chmod +x /ruta/al/script.sh # Verificar el shebang (primera línea del script) head -1 /ruta/al/script.sh # Debe ser: #!/bin/bash o #!/bin/sh

Checklist de errores comunes

ProblemaCausaSolución
La tarea no se ejecutaRutas relativas en el comandoUsar siempre rutas absolutas
La tarea no se ejecutaScript sin permisos de ejecuciónchmod +x script.sh
Error en la salidaVariables de entorno ausentesDefinir PATH, HOME, SHELL en crontab
% causa error de sintaxis% no escapado en crontabEscapar con \%
Solo funciona interactivamenteEl script depende de ~/.bashrcHacer el script autocontenido
No genera salida esperadaRedirección incorrectaUsar >> log 2>&1
✅ Truco de depuración definitivo
Crea una tarea cron de prueba que se ejecute cada minuto y registre el entorno: * * * * * env > /tmp/cron_env.txt 2>&1. Revisa el archivo generado para ver exactamente qué variables tiene cron. Compáralo con tu entorno normal (env > /tmp/mi_env.txt) y encontrarás las diferencias que causan el problema.

✅ Buenas prácticas profesionales

Tras años de experiencia con cron en entornos de producción, estas son las prácticas que distinguen a un administrador profesional:

1. Siempre redirige la salida

Cada tarea cron debe tener su salida redirigida a un archivo de log o a /dev/null. Sin redirección, cron intenta enviar la salida por email, lo que puede saturar el buzón del usuario root o, si el sistema de correo no está configurado, los mensajes se acumulan silenciosamente.

crontab — redirección correcta
# ✅ Correcto: log con timestamp 0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup_$(date +\%Y\%m\%d).log 2>&1 # ✅ Correcto: descartar salida si no necesitas log */5 * * * * /usr/local/bin/health_check.sh > /dev/null 2>&1 # ❌ Incorrecto: sin redirección (genera emails o acumula basura) # 0 3 * * * /usr/local/bin/backup.sh

2. Usa scripts, no comandos largos

Si tu tarea requiere más de un comando, crea un script aparte y llama al script desde crontab. Esto facilita la depuración, el versionado con Git y las pruebas manuales.

3. Implementa bloqueo contra ejecución concurrente

Si una tarea tarda más de lo esperado y se solapa con la siguiente ejecución, puedes tener problemas graves. Usa flock para evitarlo:

crontab — prevenir ejecución concurrente
# flock asegura que solo una instancia se ejecuta a la vez */5 * * * * /usr/bin/flock -n /tmp/mi_tarea.lock /usr/local/bin/tarea_lenta.sh # -n = no esperar si hay otra instancia (salir inmediatamente) # Sin -n, flock espera hasta que el lock se libere

4. Documenta cada tarea

Añade un comentario descriptivo antes de cada línea en tu crontab. Tu futuro yo (o quien te reemplace) lo agradecerá:

crontab — bien documentado
# ================================================ # CRONTAB DE PRODUCCIÓN — servidor web-01 # Última revisión: 2026-02-27 por admin@empresa.com # ================================================ SHELL=/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin MAILTO=alertas@empresa.com # --- BACKUPS --- # Backup incremental de BD MySQL (retención 30 días) 0 2 * * * /usr/local/bin/backup_mysql.sh >> /var/log/backup_mysql.log 2>&1 # Backup completo de archivos (cada domingo a las 3 AM) 0 3 * * 0 /usr/local/bin/backup_files.sh >> /var/log/backup_files.log 2>&1 # --- MONITORIZACIÓN --- # Health check (reinicia Apache si cae) */5 * * * * /usr/bin/flock -n /tmp/healthcheck.lock /usr/local/bin/check_apache.sh > /dev/null 2>&1 # --- LIMPIEZA --- # Purgar archivos temporales mayores de 7 días 0 4 * * 0 /usr/bin/find /tmp -type f -mtime +7 -delete

5. Versiona tus crontabs con Git

Mantén un repositorio con los crontabs de tus servidores. Ante cualquier problema, puedes restaurar la configuración anterior en segundos.

📝 Ejercicios prácticos

Pon a prueba tus conocimientos con estos ejercicios progresivos:

Ejercicio 1: Tu primer cron job

Crea una tarea cron que registre la fecha y hora actual en un archivo cada 2 minutos.

Solución — Ejercicio 1
# Editar crontab crontab -e # Añadir esta línea: */2 * * * * /bin/date >> /tmp/registro_cron.txt # Verificar después de unos minutos: cat /tmp/registro_cron.txt

Ejercicio 2: Script de backup con cron

Crea un script que haga una copia comprimida del directorio /etc/ y prográmalo para ejecutarse cada noche a las 2:00 AM.

backup_etc.sh — Ejercicio 2
#!/bin/bash # backup_etc.sh — Backup comprimido de /etc/ FECHA=$(/bin/date +\%Y\%m\%d_\%H\%M) DESTINO="/backups/etc_backup_${FECHA}.tar.gz" # Crear directorio si no existe /bin/mkdir -p /backups # Crear backup comprimido /bin/tar czf "${DESTINO}" /etc/ 2>/dev/null # Eliminar backups de más de 30 días /usr/bin/find /backups -name "etc_backup_*.tar.gz" -mtime +30 -delete echo "[$(date)] Backup completado: ${DESTINO}"
crontab — programar el backup
# Dar permisos de ejecución al script chmod +x /usr/local/bin/backup_etc.sh # Añadir al crontab: 0 2 * * * /usr/local/bin/backup_etc.sh >> /var/log/backup_etc.log 2>&1

Ejercicio 3: Monitorización con alerta

Crea un script que compruebe si el uso de disco supera el 90% y envíe una alerta. Prográmalo cada 30 minutos.

check_disk.sh — Ejercicio 3
#!/bin/bash # check_disk.sh — Alerta si el disco supera el 90% UMBRAL=90 USO=$(/bin/df / | /usr/bin/awk 'NR==2 {gsub("%",""); print $5}') if [ "${USO}" -ge "${UMBRAL}" ]; then echo "⚠️ ALERTA: Uso de disco al ${USO}% en $(hostname)" | \ /usr/bin/mail -s "Alerta disco $(hostname)" admin@empresa.com echo "[$(date)] ALERTA: disco al ${USO}%" else echo "[$(date)] OK: disco al ${USO}%" fi
crontab — programar monitorización
# Cada 30 minutos, con flock para evitar solapamiento */30 * * * * /usr/bin/flock -n /tmp/check_disk.lock /usr/local/bin/check_disk.sh >> /var/log/check_disk.log 2>&1

Ejercicio 4: Reto avanzado — Systemd timer

Convierte el backup del ejercicio 2 en un systemd timer que se ejecute a las 2:30 AM con persistencia (si el equipo está apagado, se ejecuta al arrancar) y un retardo aleatorio de hasta 5 minutos.

/etc/systemd/system/backup-etc.service
[Unit] Description=Backup diario de /etc/ [Service] Type=oneshot ExecStart=/usr/local/bin/backup_etc.sh StandardOutput=journal StandardError=journal
/etc/systemd/system/backup-etc.timer
[Unit] Description=Timer para backup diario de /etc/ [Timer] OnCalendar=*-*-* 02:30:00 Persistent=true RandomizedDelaySec=300 [Install] WantedBy=timers.target
terminal — activar
sudo systemctl daemon-reload sudo systemctl enable --now backup-etc.timer systemctl list-timers | grep backup

❓ Preguntas frecuentes sobre Automatización de tareas con Cron en Linux: guía completa

Las dudas más comunes respondidas de forma clara y directa.

Cron es el demonio (servicio) que ejecuta las tareas programadas en segundo plano. Crontab (cron table) es el archivo de configuración donde cada usuario define sus tareas. Usas el comando crontab para editar tu tabla, y el demonio cron la lee automáticamente para ejecutar las tareas en los horarios indicados.
Sí. La sintaxis es: */5 * * * * /ruta/al/script.sh — El operador */5 en el campo de minutos significa "cada 5 minutos". Puedes usar esta misma lógica con cualquier campo: */2 en horas ejecutaría cada 2 horas, por ejemplo.
Las causas más comunes son: el script no tiene permisos de ejecución (falta chmod +x), las rutas no son absolutas (cron no carga tu PATH), variables de entorno ausentes, errores de sintaxis en el crontab, o el servicio cron no está activo. Revisa el log con grep CRON /var/log/syslog para diagnosticar.
Anacron es ideal para equipos que no están encendidos 24/7, como portátiles o estaciones de trabajo. A diferencia de cron, anacron detecta las tareas que se perdieron mientras el equipo estaba apagado y las ejecuta cuando vuelve a arrancar. En servidores que funcionan continuamente, cron es suficiente.
Los systemd timers son la alternativa moderna a cron en distribuciones con systemd. Ofrecen ventajas como integración con el journal (logs centralizados), ejecución con precisión de microsegundos, dependencias entre servicios y ejecución aleatoria para evitar picos de carga. Son especialmente útiles en servidores con systemd donde se necesita monitorización avanzada.
Para redirigir tanto stdout como stderr a un archivo de log, usa: 0 3 * * * /script.sh >> /var/log/mi_script.log 2>&1 — El >> añade al final del archivo y 2>&1 redirige los errores al mismo destino. Para descartar la salida completamente: comando > /dev/null 2>&1.
Valora este artículo

💬 Foro de discusión

¿Tienes dudas sobre Automatización de tareas con Cron en Linux: guía completa? Comparte tu pregunta con la comunidad.

¿Tienes cuenta? o comenta como invitado ↓

Todavía no hay mensajes. ¡Sé el primero en participar!

🚀 ¿Quieres dominar Linux profesionalmente?
Cursos bonificados por FUNDAE para empresas — formación 100% subvencionada
Ver cursos de Linux →