Automatización de tareas con Cron en Linux
Cron es un demonio de sistema en Unix y sistemas operativos similares que permite ejecutar comandos y scripts de manera automatizada en momentos específicos. Su nombre deriva de “chronos” (tiempo en griego), y es una herramienta fundamental para la administración de sistemas y automatización de tareas.
Características Principales
Section titled “Características Principales”- Ejecución programada: Permite ejecutar comandos en intervalos específicos
- Automatización: Elimina la necesidad de intervención manual para tareas repetitivas
- Flexibilidad: Admite programaciones desde cada minuto hasta anuales
- Multi-usuario: Cada usuario puede tener su propio conjunto de tareas programadas
- Persistencia: Las tareas se ejecutan incluso cuando el usuario no está conectado
Casos de Uso Comunes
Section titled “Casos de Uso Comunes”- Respaldos automáticos del sistema
- Limpieza de archivos temporales
- Envío de reportes por email
- Monitoreo del sistema
- Actualizaciones de software
- Rotación de logs
- Sincronización de datos
Conceptos Básicos
Section titled “Conceptos Básicos”El Demonio Cron (crond)
Section titled “El Demonio Cron (crond)”El demonio cron es un proceso que se ejecuta en segundo plano y verifica cada minuto si hay tareas programadas para ejecutar. Dependiendo de la distribución, puede llamarse:
cron(Ubuntu, Debian)crond(RHEL, CentOS, Fedora)cronie(algunas distribuciones modernas)
Crontab (Cron Table)
Section titled “Crontab (Cron Table)”Crontab es tanto el comando utilizado para editar las tareas programadas como el archivo que contiene estas tareas. Existen diferentes tipos:
- Crontab de usuario:
~/.crontabo/var/spool/cron/crontabs/usuario - Crontab del sistema:
/etc/crontab - Directorios del sistema:
/etc/cron.d/,/etc/cron.daily/,/etc/cron.weekly/,/etc/cron.monthly/
Instalación y Configuración
Section titled “Instalación y Configuración”Verificar si Cron está Instalado
Section titled “Verificar si Cron está Instalado”# Verificar el estado del servicio cronsudo systemctl status cron
# En sistemas con crondsudo systemctl status crond
# Verificar si el proceso está corriendops aux | grep cronInstalación en Diferentes Distribuciones
Section titled “Instalación en Diferentes Distribuciones”# Ubuntu/Debiansudo apt updatesudo apt install cron
# RHEL/CentOS/Fedorasudo yum install cronie# o en versiones más nuevassudo dnf install cronie
# Arch Linuxsudo pacman -S cronieHabilitar y Iniciar el Servicio
Section titled “Habilitar y Iniciar el Servicio”# Habilitar cron para que se inicie automáticamentesudo systemctl enable cronsudo systemctl start cron
# Para crondsudo systemctl enable crondsudo systemctl start crondSintaxis de Cron
Section titled “Sintaxis de Cron”Formato Básico
Section titled “Formato Básico”* * * * * comando_a_ejecutar│ │ │ │ ││ │ │ │ ││ │ │ │ └─── Día de la semana (0-6, donde 0 = Domingo)│ │ │ └───── Mes (1-12)│ │ └─────── Día del mes (1-31)│ └───────── Hora (0-23)└─────────── Minuto (0-59)Valores Permitidos
Section titled “Valores Permitidos”| Campo | Rango | Descripción |
|---|---|---|
| Minuto | 0-59 | Minuto específico de la hora |
| Hora | 0-23 | Hora en formato 24h |
| Día del mes | 1-31 | Día específico del mes |
| Mes | 1-12 o JAN-DEC | Mes del año |
| Día de la semana | 0-6 o SUN-SAT | Día de la semana (0 y 7 = Domingo) |
Caracteres Especiales
Section titled “Caracteres Especiales”| Símbolo | Significado | Ejemplo |
|---|---|---|
* | Todos los valores | * * * * * = cada minuto |
, | Separar múltiples valores | 0,15,30,45 = minutos 0, 15, 30, 45 |
- | Rango de valores | 1-5 = lunes a viernes |
/ | Intervalos (step) | */10 = cada 10 unidades |
L | Último (día del mes/semana) | L = último día del mes |
W | Día laboral más cercano | 15W = día laboral más cercano al 15 |
# | N-ésima ocurrencia | MON#2 = segundo lunes del mes |
? | No especificar valor | Usado en día del mes o día de la semana |
Para facilitar su uso y comprobar que la sintaxis que indicamos hace realmente lo que queremos, podemos utilizar la web: https://crontab.guru/
Comandos de Crontab
Section titled “Comandos de Crontab”Comandos Principales
Section titled “Comandos Principales”# Editar crontab del usuario actualcrontab -e
# Listar tareas del usuario actualcrontab -l
# Eliminar todas las tareas del usuario actualcrontab -r
# Eliminar con confirmacióncrontab -i -r
# Ver la fecha de última modificacióncrontab -vGestión de Crontabs de Otros Usuarios (como root)
Section titled “Gestión de Crontabs de Otros Usuarios (como root)”# Editar crontab de un usuario específicosudo crontab -u usuario -e
# Listar tareas de un usuario específicosudo crontab -u usuario -l
# Eliminar crontab de un usuario específicosudo crontab -u usuario -rImportar/Exportar Crontabs
Section titled “Importar/Exportar Crontabs”# Exportar crontab a un archivocrontab -l > mi_crontab_backup.txt
# Importar crontab desde un archivocrontab mi_crontab_backup.txt
# Agregar tareas manteniendo las existentescrontab -l > temp_crontabecho "0 2 * * * /ruta/al/script.sh" >> temp_crontabcrontab temp_crontabrm temp_crontabVariables de Entorno
Section titled “Variables de Entorno”Problema con Variables de Entorno
Section titled “Problema con Variables de Entorno”Cron ejecuta comandos en un entorno muy limitado, sin cargar archivos como .bashrc, .bash_profile, o /etc/profile. Esto puede causar que scripts funcionen manualmente pero fallen en cron.
Métodos para Definir Variables de Entorno
Section titled “Métodos para Definir Variables de Entorno”1. Definir Variables Directamente en Crontab
Section titled “1. Definir Variables Directamente en Crontab”# Abrir crontab para editarcrontab -e
# Agregar variables al inicio del archivoSHELL=/bin/bashPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binMAILTO=admin@example.comHOME=/home/usuarioLANG=es_ES.UTF-8
# Luego agregar las tareas0 2 * * * /ruta/al/script.sh2. Usar un Script Wrapper
Section titled “2. Usar un Script Wrapper”#!/bin/bashsource /home/usuario/.bashrcsource /home/usuario/.bash_profile/ruta/al/script_principal.sh
# En crontab0 2 * * * /home/usuario/scripts/wrapper.sh3. Usar BASH_ENV
Section titled “3. Usar BASH_ENV”# En crontabBASH_ENV=/etc/profile0 2 * * * /ruta/al/script.shVariables de Cron Importantes
Section titled “Variables de Cron Importantes”| Variable | Descripción | Ejemplo |
|---|---|---|
SHELL | Shell utilizado para ejecutar comandos | SHELL=/bin/bash |
PATH | Rutas donde buscar ejecutables | PATH=/usr/local/bin:/usr/bin:/bin |
MAILTO | Email para enviar salida de comandos | MAILTO=admin@example.com |
HOME | Directorio home del usuario | HOME=/home/usuario |
LOGNAME | Nombre del usuario | LOGNAME=usuario |
USER | Nombre del usuario | USER=usuario |
Depurar Variables de Entorno
Section titled “Depurar Variables de Entorno”# Crear una tarea que exporte todas las variables* * * * * env > /tmp/cron-env.log
# Comparar con el entorno del shellenv > /tmp/shell-env.logdiff /tmp/cron-env.log /tmp/shell-env.logEjemplos Prácticos
Section titled “Ejemplos Prácticos”Ejemplos Básicos
Section titled “Ejemplos Básicos”# Ejecutar cada minuto* * * * * /ruta/al/script.sh
# Ejecutar cada hora en punto0 * * * * /ruta/al/script.sh
# Ejecutar diariamente a las 2:30 AM30 2 * * * /ruta/al/script.sh
# Ejecutar semanalmente los domingos a las 3:00 AM0 3 * * 0 /ruta/al/script.sh
# Ejecutar mensualmente el día 1 a las 4:00 AM0 4 1 * * /ruta/al/script.shEjemplos con Intervalos
Section titled “Ejemplos con Intervalos”# Cada 5 minutos*/5 * * * * /ruta/al/script.sh
# Cada 2 horas0 */2 * * * /ruta/al/script.sh
# Cada 10 minutos entre 9 AM y 5 PM*/10 9-17 * * * /ruta/al/script.sh
# Días laborales cada hora de 9 AM a 5 PM0 9-17 * * 1-5 /ruta/al/script.shEjemplos con Múltiples Valores
Section titled “Ejemplos con Múltiples Valores”# Ejecutar a las 8:30 AM y 6:30 PM todos los días30 8,18 * * * /ruta/al/script.sh
# Ejecutar lunes, miércoles y viernes a las 2:15 PM15 14 * * 1,3,5 /ruta/al/script.sh
# Ejecutar los días 1 y 15 de cada mes0 0 1,15 * * /ruta/al/script.shEjemplos Avanzados
Section titled “Ejemplos Avanzados”# Ejecutar cada 15 minutos excepto durante la hora de almuerzo*/15 0-11,13-23 * * * /ruta/al/script.sh
# Backup semanal los domingos excepto en diciembre0 2 * 1-11 0 /usr/local/bin/backup.sh
# Mantenimiento el primer lunes de cada mes0 3 1-7 * 1 /usr/local/bin/maintenance.sh
# Limpeza de logs diaria, pero duplicada los viernes para limpieza profunda0 2 * * * /usr/local/bin/cleanup-daily.sh0 3 * * 5 /usr/local/bin/cleanup-deep.shRedirección de Salida
Section titled “Redirección de Salida”# Redirigir salida a un archivo0 2 * * * /ruta/al/script.sh >> /var/log/script.log 2>&1
# Separar stdout y stderr0 2 * * * /ruta/al/script.sh >> /var/log/script.log 2>> /var/log/script-error.log
# Descartar toda salida0 2 * * * /ruta/al/script.sh > /dev/null 2>&1
# Enviar solo errores por email (manteniendo MAILTO configurado)0 2 * * * /ruta/al/script.sh > /dev/nullGestión de Logs
Section titled “Gestión de Logs”Ubicaciones de Logs del Sistema
Section titled “Ubicaciones de Logs del Sistema”# Logs principales en diferentes distribuciones/var/log/cron # RHEL, CentOS/var/log/cron.log # Ubuntu, Debian/var/log/syslog # Ubuntu, Debian (general)/var/log/messages # RHEL, CentOS (general)Habilitar Logging de Cron
Section titled “Habilitar Logging de Cron”En Sistemas con rsyslog
Section titled “En Sistemas con rsyslog”# Editar configuración de rsyslogsudo vi /etc/rsyslog.conf
# Agregar o descomentar la línea:cron.* /var/log/cron.log
# Reiniciar rsyslogsudo systemctl restart rsyslogEn Sistemas con systemd
Section titled “En Sistemas con systemd”# Ver logs de cron con journalctljournalctl -u cron
# Logs en tiempo realjournalctl -u cron -f
# Logs de un período específicojournalctl -u cron --since "2024-01-01" --until "2024-01-02"
# Logs con mayor detallejournalctl -u cron -n 50 --no-pagerComandos Útiles para Analizar Logs
Section titled “Comandos Útiles para Analizar Logs”# Ver ejecuciones recientes de crongrep CRON /var/log/syslog | tail -20
# Buscar errores en logs de crongrep -i "error\|failed" /var/log/cron
# Filtrar por usuario específicogrep "usuario" /var/log/cron
# Filtrar por comando específicogrep "backup.sh" /var/log/cron
# Ver logs de hoygrep "$(date +%b\ %d)" /var/log/cronCrear Logs Personalizados para Scripts
Section titled “Crear Logs Personalizados para Scripts”#!/bin/bashLOG_FILE="/var/log/mi_script.log"DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$DATE] Iniciando script..." >> $LOG_FILE
# Tu código aquíif comando_principal; then echo "[$DATE] Script ejecutado exitosamente" >> $LOG_FILEelse echo "[$DATE] ERROR: Script falló" >> $LOG_FILE exit 1fi
echo "[$DATE] Script finalizado" >> $LOG_FILEDepuración y Solución de Problemas
Section titled “Depuración y Solución de Problemas”Problemas Comunes y Soluciones
Section titled “Problemas Comunes y Soluciones”1. El Script Funciona Manualmente pero No en Cron
Section titled “1. El Script Funciona Manualmente pero No en Cron”Causa: Diferencias en el entorno de ejecución.
Solución:
# Comparar entornos# En cron:* * * * * env > /tmp/cron-env.log
# En terminal:env > /tmp/shell-env.logdiff /tmp/cron-env.log /tmp/shell-env.log
# Usar rutas absolutas* * * * * /usr/bin/python3 /home/usuario/script.py
# Definir PATH completoPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin* * * * * python3 /home/usuario/script.py2. Permisos Insuficientes
Section titled “2. Permisos Insuficientes”Solución:
# Verificar permisos del scriptls -la /ruta/al/script.sh
# Dar permisos de ejecuciónchmod +x /ruta/al/script.sh
# Verificar que el usuario puede ejecutar el scriptsudo -u usuario /ruta/al/script.sh3. Comando o Ruta No Encontrada
Section titled “3. Comando o Ruta No Encontrada”Solución:
# Encontrar la ruta completa de un comandowhich comandowhereis comando
# Usar rutas absolutas en el script#!/bin/bash/usr/bin/rsync -av /origen/ /destino//bin/echo "Backup completado" >> /var/log/backup.log4. Variables de Entorno Faltantes
Section titled “4. Variables de Entorno Faltantes”Solución:
# Crear script wrapper que cargue el entorno#!/bin/bashsource ~/.bashrcsource ~/.profile/ruta/al/script/original.sh
# En crontab0 2 * * * /ruta/al/wrapper.shTécnicas de Depuración
Section titled “Técnicas de Depuración”1. Test con Salida Detallada
Section titled “1. Test con Salida Detallada”# Crear un script de prueba#!/bin/bashecho "=== Inicio del script: $(date) ==="echo "Usuario: $(whoami)"echo "Directorio actual: $(pwd)"echo "PATH: $PATH"env | sortecho "=== Ejecutando comando principal ==="# tu comando aquíecho "=== Fin del script: $(date) ==="
# En crontab con redirección completa*/5 * * * * /ruta/al/script_test.sh >> /tmp/debug_cron.log 2>&12. Simular el Entorno de Cron
Section titled “2. Simular el Entorno de Cron”# Ejecutar comando con entorno mínimo como cronenv -i HOME=/home/usuario PATH=/usr/bin:/bin bash -c '/ruta/al/script.sh'
# Probar con el mismo usuario que ejecutará cronsudo -u usuario env -i HOME=/home/usuario PATH=/usr/bin:/bin /ruta/al/script.sh3. Verificar Syntax de Cron
Section titled “3. Verificar Syntax de Cron”# Usar herramientas online como crontab.guru# O crear un script de verificación#!/bin/bash# Verificar que cron esté corriendosystemctl is-active cron
# Listar trabajos actualescrontab -l
# Verificar logs recientestail -f /var/log/cronScript de Diagnóstico Completo
Section titled “Script de Diagnóstico Completo”#!/bin/bash# diagnóstico_cron.sh
echo "=== DIAGNÓSTICO DE CRON ==="echo "Fecha: $(date)"echo
echo "1. Estado del servicio cron:"systemctl status cron --no-pagerecho
echo "2. Cron está corriendo:"pgrep cronecho
echo "3. Tareas programadas del usuario actual:"crontab -lecho
echo "4. Variables de entorno en cron:"# Crear tarea temporal para capturar entorno(crontab -l; echo "* * * * * env > /tmp/cron_env_check") | crontab -sleep 70 # Esperar que se ejecutecat /tmp/cron_env_checkrm /tmp/cron_env_check# Remover la tarea temporalcrontab -l | grep -v "env > /tmp/cron_env_check" | crontab -echo
echo "5. Logs recientes de cron:"tail -20 /var/log/syslog | grep CRONecho
echo "6. Permisos de directorio de cron:"ls -la /var/spool/cron/crontabs/echo
echo "=== FIN DEL DIAGNÓSTICO ==="Mejores Prácticas de Seguridad
Section titled “Mejores Prácticas de Seguridad”1. Gestión de Permisos
Section titled “1. Gestión de Permisos”# Permisos recomendados para scriptschmod 750 /ruta/al/script.sh # rwxr-x---chown usuario:grupo /ruta/al/script.sh
# Verificar permisos de archivos crontabls -la /var/spool/cron/crontabs/
# Los archivos crontab deben tener permisos 600chmod 600 /var/spool/cron/crontabs/usuario2. Restricciones de Acceso a Cron
Section titled “2. Restricciones de Acceso a Cron”# Permitir solo usuarios específicosecho "usuario1" >> /etc/cron.allowecho "usuario2" >> /etc/cron.allow
# Denegar usuarios específicosecho "usuario_restringido" >> /etc/cron.deny
# Si existe /etc/cron.allow, solo usuarios listados pueden usar cron# Si solo existe /etc/cron.deny, todos excepto los listados pueden usar cron3. Evitar Información Sensible en Crontab
Section titled “3. Evitar Información Sensible en Crontab”# MALO: contraseñas en línea de comandos0 2 * * * mysqldump -u root -pmysecretpass database > backup.sql
# BUENO: usar archivos de configuración0 2 * * * mysqldump --defaults-file=/etc/mysql/backup.cnf database > backup.sql
# BUENO: usar variables de entornoDB_PASSWORD=mysecretpass0 2 * * * mysqldump -u root -p$DB_PASSWORD database > backup.sql4. Validación de Entrada en Scripts
Section titled “4. Validación de Entrada en Scripts”#!/bin/bash# Script con validaciones de seguridad
# Verificar que el script se ejecuta como el usuario correctoif [[ "$(whoami)" != "expected_user" ]]; then echo "ERROR: Script debe ejecutarse como expected_user" exit 1fi
# Validar que los directorios existenSOURCE_DIR="/path/to/source"DEST_DIR="/path/to/destination"
if [[ ! -d "$SOURCE_DIR" ]]; then echo "ERROR: Directorio fuente no existe: $SOURCE_DIR" exit 1fi
if [[ ! -d "$DEST_DIR" ]]; then echo "ERROR: Directorio destino no existe: $DEST_DIR" exit 1fi
# Usar rutas absolutas/usr/bin/rsync -av "$SOURCE_DIR/" "$DEST_DIR/"5. Monitoreo y Auditoría
Section titled “5. Monitoreo y Auditoría”# Script de auditoría de trabajos cron#!/bin/bashecho "=== AUDITORÍA DE CRON $(date) ===" >> /var/log/cron_audit.log
# Listar todos los crontabsfor user in $(cut -f1 -d: /etc/passwd); do if crontab -u "$user" -l >/dev/null 2>&1; then echo "Usuario $user tiene crontab:" >> /var/log/cron_audit.log crontab -u "$user" -l >> /var/log/cron_audit.log echo "---" >> /var/log/cron_audit.log fidone
# Verificar integridad de archivos críticosmd5sum /etc/crontab >> /var/log/cron_audit.logfind /etc/cron.d/ -type f -exec md5sum {} \; >> /var/log/cron_audit.log6. Configuración Segura del Sistema
Section titled “6. Configuración Segura del Sistema”# En /etc/crontab, definir variables segurasSHELL=/bin/bashPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binMAILTO=admin@example.com
# Configurar logrotate para logs de croncat > /etc/logrotate.d/cron << EOF/var/log/cron { daily missingok rotate 14 compress notifempty create 644 root root}EOFCron vs Anacron
Section titled “Cron vs Anacron”Diferencias Principales
Section titled “Diferencias Principales”| Característica | Cron | Anacron |
|---|---|---|
| Tipo de servicio | Demonio | No es demonio |
| Sistemas objetivo | Servidores 24/7 | Desktops/laptops |
| Precisión mínima | 1 minuto | 1 día |
| Tareas perdidas | No se ejecutan | Se ejecutan al reiniciar |
| Configuración | Crontab individual | /etc/anacrontab global |
| Usuarios | Multi-usuario | Solo root (por defecto) |
Cuándo Usar Cada Uno
Section titled “Cuándo Usar Cada Uno”Usar Cron cuando:
Section titled “Usar Cron cuando:”- El sistema está siempre encendido (servidores)
- Necesitas precisión al minuto/hora
- Requieres tareas críticas en tiempo específico
- Necesitas configuración por usuario
Usar Anacron cuando:
Section titled “Usar Anacron cuando:”- El sistema no está siempre encendido
- Las tareas pueden tolerar demora
- Prefieres que las tareas se ejecuten eventualmente
- Trabajas en desktops/laptops
Configuración de Anacron
Section titled “Configuración de Anacron”# Instalar anacronsudo apt install anacron # Ubuntu/Debiansudo yum install cronie-anacron # RHEL/CentOS
# Archivo de configuración: /etc/anacrontab# Formato: período_en_días retraso_en_minutos identificador comando
# Ejemplo de /etc/anacrontabSHELL=/bin/shPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/binHOME=/rootLOGNAME=root
# período retraso job-identifier comando1 5 daily-backup /usr/local/bin/backup.sh7 10 weekly-cleanup /usr/local/bin/cleanup.sh@monthly 15 monthly-report /usr/local/bin/report.shIntegración de Cron y Anacron
Section titled “Integración de Cron y Anacron”# Cron puede llamar a anacron para sistemas híbridos# En /etc/crontab0 6 * * * root anacron -s
# Esto ejecuta anacron diariamente a las 6 AM# Anacron verificará y ejecutará tareas pendientesScripts de Ejemplo
Section titled “Scripts de Ejemplo”Script de Respaldo Completo
Section titled “Script de Respaldo Completo”#!/bin/bash# backup.sh - Script completo de respaldo con logs y notificaciones
# ConfiguraciónSOURCE_DIR="/home/usuario"BACKUP_DIR="/backup"LOG_FILE="/var/log/backup.log"RETENTION_DAYS=30EMAIL="admin@example.com"DATE=$(date +%Y%m%d_%H%M%S)BACKUP_NAME="backup_$DATE.tar.gz"
# Función de logginglog() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE}
# Función para enviar notificacionesnotify() { local subject="$1" local message="$2" echo "$message" | mail -s "$subject" $EMAIL log "Notificación enviada: $subject"}
# Inicio del scriptlog "=== INICIO DEL BACKUP ==="log "Respaldo desde: $SOURCE_DIR"log "Respaldo hacia: $BACKUP_DIR/$BACKUP_NAME"
# Verificar que existe el directorio fuenteif [[ ! -d "$SOURCE_DIR" ]]; then log "ERROR: Directorio fuente no existe: $SOURCE_DIR" notify "Backup FAILED" "Directorio fuente no existe: $SOURCE_DIR" exit 1fi
# Crear directorio de backup si no existeif [[ ! -d "$BACKUP_DIR" ]]; then mkdir -p "$BACKUP_DIR" log "Directorio de backup creado: $BACKUP_DIR"fi
# Verificar espacio disponibleAVAILABLE_SPACE=$(df "$BACKUP_DIR" | awk 'NR==2 {print $4}')REQUIRED_SPACE=$(du -s "$SOURCE_DIR" | awk '{print $1}')
if [[ $AVAILABLE_SPACE -lt $REQUIRED_SPACE ]]; then log "ERROR: Espacio insuficiente. Disponible: ${AVAILABLE_SPACE}K, Requerido: ${REQUIRED_SPACE}K" notify "Backup FAILED" "Espacio insuficiente en disco" exit 1fi
# Realizar el backuplog "Iniciando creación del archivo de respaldo..."if tar -czf "$BACKUP_DIR/$BACKUP_NAME" -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")" 2>> $LOG_FILE; then BACKUP_SIZE=$(du -h "$BACKUP_DIR/$BACKUP_NAME" | awk '{print $1}') log "Backup completado exitosamente. Tamaño: $BACKUP_SIZE" notify "Backup SUCCESS" "Backup completado. Archivo: $BACKUP_NAME, Tamaño: $BACKUP_SIZE"else log "ERROR: Fallo en la creación del backup" notify "Backup FAILED" "Error durante la creación del archivo de backup" exit 1fi
# Limpiar backups antiguoslog "Limpiando backups antiguos (más de $RETENTION_DAYS días)..."DELETED_COUNT=$(find "$BACKUP_DIR" -name "backup_*.tar.gz" -type f -mtime +$RETENTION_DAYS -delete -print | wc -l)log "Eliminados $DELETED_COUNT archivos de backup antiguos"
# Verificar integridad del backuplog "Verificando integridad del backup..."if tar -tzf "$BACKUP_DIR/$BACKUP_NAME" > /dev/null 2>&1; then log "Verificación de integridad exitosa"else log "ERROR: Archivo de backup corrupto" notify "Backup CORRUPTED" "El archivo de backup no pasó la verificación de integridad" exit 1fi
log "=== FIN DEL BACKUP ==="exit 0Script de Monitoreo del Sistema
Section titled “Script de Monitoreo del Sistema”#!/bin/bash# system_monitor.sh - Monitoreo básico del sistema
LOG_FILE="/var/log/system_monitor.log"ALERT_EMAIL="admin@example.com"DATE=$(date '+%Y-%m-%d %H:%M:%S')
# Umbrales de alertaCPU_THRESHOLD=80MEMORY_THRESHOLD=85DISK_THRESHOLD=90
log() { echo "[$DATE] $1" >> $LOG_FILE}
alert() { local subject="$1" local message="$2" log "ALERT: $subject - $message" echo "$message" | mail -s "SISTEMA: $subject" $ALERT_EMAIL}
# Verificar CPUCPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F'%' '{print $1}')CPU_USAGE_INT=${CPU_USAGE%.*} # Convertir a entero
if [[ $CPU_USAGE_INT -gt $CPU_THRESHOLD ]]; then alert "CPU Alta" "Uso de CPU: ${CPU_USAGE}% (umbral: ${CPU_THRESHOLD}%)"fi
# Verificar MemoriaMEMORY_USAGE=$(free | awk 'FNR==2{printf "%.0f", $3/($3+$4)*100}')
if [[ $MEMORY_USAGE -gt $MEMORY_THRESHOLD ]]; then alert "Memoria Alta" "Uso de memoria: ${MEMORY_USAGE}% (umbral: ${MEMORY_THRESHOLD}%)"fi
# Verificar Discosdf -h | awk 'NR>1 {print $5 " " $6}' | while read output; do USAGE=$(echo $output | awk '{print $1}' | sed 's/%//g') PARTITION=$(echo $output | awk '{print $2}')
if [[ $USAGE -gt $DISK_THRESHOLD ]]; then alert "Disco Lleno" "Partición $PARTITION: ${USAGE}% (umbral: ${DISK_THRESHOLD}%)" fidone
# Verificar servicios críticosSERVICES=("ssh" "nginx" "mysql")
for service in "${SERVICES[@]}"; do if ! systemctl is-active --quiet $service; then alert "Servicio Inactivo" "El servicio $service no está corriendo" fidone
# Verificar carga del sistemaLOAD_AVERAGE=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1 | tr -d ' ')LOAD_THRESHOLD="2.0"
if (( $(echo "$LOAD_AVERAGE > $LOAD_THRESHOLD" | bc -l) )); then alert "Carga Alta" "Load average: $LOAD_AVERAGE (umbral: $LOAD_THRESHOLD)"fi
log "Monitoreo completado - CPU: ${CPU_USAGE}%, RAM: ${MEMORY_USAGE}%, Load: $LOAD_AVERAGE"Script de Limpieza de Logs
Section titled “Script de Limpieza de Logs”#!/bin/bash# cleanup_logs.sh - Limpieza automática de logs
LOG_DIRS=("/var/log" "/tmp" "/var/tmp")MAX_SIZE_MB=100MAX_AGE_DAYS=30REPORT_FILE="/var/log/cleanup_report.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $REPORT_FILE}
log "=== INICIO DE LIMPIEZA DE LOGS ==="
TOTAL_FREED=0
for dir in "${LOG_DIRS[@]}"; do if [[ -d "$dir" ]]; then log "Procesando directorio: $dir"
# Limpiar archivos por tamaño while IFS= read -r -d '' file; do SIZE_MB=$(du -m "$file" | cut -f1) if [[ $SIZE_MB -gt $MAX_SIZE_MB ]]; then log "Truncando archivo grande: $file (${SIZE_MB}MB)" > "$file" # Truncar archivo TOTAL_FREED=$((TOTAL_FREED + SIZE_MB)) fi done < <(find "$dir" -type f -name "*.log" -print0)
# Limpiar archivos por edad DELETED_COUNT=0 while IFS= read -r -d '' file; do log "Eliminando archivo antiguo: $file" DELETED_COUNT=$((DELETED_COUNT + 1)) done < <(find "$dir" -type f -name "*.log.*" -mtime +$MAX_AGE_DAYS -delete -print0)
if [[ $DELETED_COUNT -gt 0 ]]; then log "Eliminados $DELETED_COUNT archivos antiguos de $dir" fi
# Comprimir logs rotados no comprimidos find "$dir" -type f -name "*.log.[0-9]*" ! -name "*.gz" -exec gzip {} \; COMPRESSED_COUNT=$(find "$dir" -type f -name "*.log.[0-9]*.gz" -newer "$REPORT_FILE" | wc -l) if [[ $COMPRESSED_COUNT -gt 0 ]]; then log "Comprimidos $COMPRESSED_COUNT archivos de log" fi fidone
# Limpiar archivos core dumpsCORE_FILES=$(find /tmp /var/tmp -name "core.*" -type f -mtime +7 -delete -print | wc -l)if [[ $CORE_FILES -gt 0 ]]; then log "Eliminados $CORE_FILES archivos core dump"fi
# Reporte finalDISK_FREED_MB=$((TOTAL_FREED))log "Limpieza completada. Espacio liberado aproximado: ${DISK_FREED_MB}MB"log "=== FIN DE LIMPIEZA ==="
# Enviar reporte si se liberó mucho espacioif [[ $DISK_FREED_MB -gt 1000 ]]; then mail -s "Limpieza de logs: ${DISK_FREED_MB}MB liberados" admin@example.com < $REPORT_FILEfiCasos de Uso Avanzados
Section titled “Casos de Uso Avanzados”1. Backup Diferencial Automático
Section titled “1. Backup Diferencial Automático”#!/bin/bash# differential_backup.sh - Sistema de backup diferencial
BACKUP_BASE="/backup"SOURCE="/home/usuario"FULL_BACKUP_DAY=0 # DomingoSNAPSHOT_FILE="$BACKUP_BASE/snapshot.file"
DOW=$(date +%w) # Día de la semana (0=domingo)
if [[ $DOW -eq $FULL_BACKUP_DAY ]] || [[ ! -f "$SNAPSHOT_FILE" ]]; then # Backup completo BACKUP_TYPE="full" tar --listed-incremental="$SNAPSHOT_FILE" -czf "$BACKUP_BASE/full_$(date +%Y%m%d).tar.gz" "$SOURCE"else # Backup incremental BACKUP_TYPE="incremental" tar --listed-incremental="$SNAPSHOT_FILE" -czf "$BACKUP_BASE/inc_$(date +%Y%m%d).tar.gz" "$SOURCE"fi
echo "Backup $BACKUP_TYPE completado: $(date)"2. Sincronización de Datos con Verificación
Section titled “2. Sincronización de Datos con Verificación”#!/bin/bash# sync_with_verification.sh - Sincronización con verificación de integridad
SOURCE="/data/important"DEST="/backup/sync"LOG="/var/log/sync.log"
# Sincronizar con rsyncrsync -av --delete --checksum "$SOURCE/" "$DEST/" >> $LOG 2>&1
# Verificar integridad comparando checksumsif diff <(find "$SOURCE" -type f -exec md5sum {} \; | sort) \ <(find "$DEST" -type f -exec md5sum {} \; | sort) > /dev/null; then echo "[$(date)] Sincronización exitosa y verificada" >> $LOGelse echo "[$(date)] ERROR: Fallo en la verificación de integridad" >> $LOG # Enviar alerta mail -s "Error en sincronización" admin@example.com << EOFLa sincronización de datos falló la verificación de integridad.Revisar inmediatamente el log: $LOGEOFfi3. Gestión Dinámica de Recursos
Section titled “3. Gestión Dinámica de Recursos”#!/bin/bash# dynamic_resource_management.sh - Ajuste dinámico basado en carga
# Obtener carga actual del sistemaLOAD=$(uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' ')LOAD_INT=${LOAD%.*}
# Ajustar comportamiento según la cargaif [[ $LOAD_INT -lt 1 ]]; then # Carga baja: ejecutar tareas pesadas /usr/local/bin/heavy_maintenance.sh /usr/local/bin/deep_scan.shelif [[ $LOAD_INT -lt 3 ]]; then # Carga media: solo tareas esenciales /usr/local/bin/essential_tasks.shelse # Carga alta: solo monitoreo /usr/local/bin/quick_health_check.shfi
echo "[$(date)] Gestión dinámica ejecutada con carga: $LOAD"4. Rotación Inteligente de Backups
Section titled “4. Rotación Inteligente de Backups”#!/bin/bash# intelligent_rotation.sh - Rotación de backups con política inteligente
BACKUP_DIR="/backup"PREFIX="backup_"
# Política de retención:# - Diarios: últimos 7 días# - Semanales: últimas 4 semanas# - Mensuales: últimos 12 meses# - Anuales: indefinido
# Mantener backups diarios (últimos 7)find "$BACKUP_DIR" -name "${PREFIX}daily_*" -type f -mtime +7 -delete
# Crear backup semanal (solo domingos)if [[ $(date +%w) -eq 0 ]]; then LATEST_DAILY=$(ls -1 "$BACKUP_DIR"/${PREFIX}daily_* 2>/dev/null | tail -1) if [[ -n "$LATEST_DAILY" ]]; then cp "$LATEST_DAILY" "$BACKUP_DIR/${PREFIX}weekly_$(date +%Y%m%d).tar.gz" fifi
# Mantener backups semanales (últimas 4 semanas)find "$BACKUP_DIR" -name "${PREFIX}weekly_*" -type f -mtime +28 -delete
# Crear backup mensual (primer día del mes)if [[ $(date +%d) -eq 01 ]]; then LATEST_WEEKLY=$(ls -1 "$BACKUP_DIR"/${PREFIX}weekly_* 2>/dev/null | tail -1) if [[ -n "$LATEST_WEEKLY" ]]; then cp "$LATEST_WEEKLY" "$BACKUP_DIR/${PREFIX}monthly_$(date +%Y%m).tar.gz" fifi
# Mantener backups mensuales (últimos 12 meses)find "$BACKUP_DIR" -name "${PREFIX}monthly_*" -type f -mtime +365 -deleteConfiguración en Crontab para Casos Avanzados
Section titled “Configuración en Crontab para Casos Avanzados”# Ejemplo de crontab completo para administración de sistemaSHELL=/bin/bashPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binMAILTO=admin@example.comHOME=/root
# Backup diferencial (diario a las 2 AM)0 2 * * * /usr/local/bin/differential_backup.sh >> /var/log/backup.log 2>&1
# Sincronización con verificación (cada 4 horas)0 */4 * * * /usr/local/bin/sync_with_verification.sh
# Monitoreo del sistema (cada 10 minutos)*/10 * * * * /usr/local/bin/system_monitor.sh
# Limpieza de logs (diario a las 3 AM)0 3 * * * /usr/local/bin/cleanup_logs.sh
# Gestión dinámica de recursos (cada hora)0 * * * * /usr/local/bin/dynamic_resource_management.sh
# Rotación inteligente de backups (diario a las 4 AM)0 4 * * * /usr/local/bin/intelligent_rotation.sh
# Verificación de seguridad (semanal, lunes a las 5 AM)0 5 * * 1 /usr/local/bin/security_audit.sh
# Actualización de sistema (mensual, primer sábado a las 6 AM)0 6 1-7 * 6 /usr/local/bin/system_update.sh
# Reporte mensual (último día del mes a las 11 PM)0 23 28-31 * * [ "$(date +\%d -d tomorrow)" = "01" ] && /usr/local/bin/monthly_report.shReferencias y Recursos Adicionales
Section titled “Referencias y Recursos Adicionales”Documentación Oficial
Section titled “Documentación Oficial”- Manual de Cron:
man 8 cron - Manual de Crontab:
man 5 crontab - Manual de Anacron:
man 8 anacron
Herramientas Útiles
Section titled “Herramientas Útiles”- Crontab Guru: https://crontab.guru - Traductor de expresiones cron
- Cron Calculator: Herramientas online para calcular próximas ejecuciones
- Crontab Editor: Editores visuales para crear expresiones cron
Comandos de Verificación Rápida
Section titled “Comandos de Verificación Rápida”# Verificar sintaxis de una expresión cron# No existe comando nativo, usar herramientas online
# Calcular próxima ejecución# Crear script personalizado o usar herramientas como 'dateutils'
# Monitorear ejecución en tiempo realtail -f /var/log/cron
# Listar todos los crontabs del sistemafor user in $(cut -f1 -d: /etc/passwd); do echo "=== $user ===" sudo crontab -u "$user" -l 2>/dev/null || echo "No crontab"doneArchivos Importantes del Sistema
Section titled “Archivos Importantes del Sistema”/etc/crontab # Crontab principal del sistema/etc/cron.d/ # Directorio para crons del sistema/etc/cron.daily/ # Scripts diarios/etc/cron.weekly/ # Scripts semanales/etc/cron.monthly/ # Scripts mensuales/etc/cron.hourly/ # Scripts por hora/var/spool/cron/crontabs/ # Crontabs de usuarios individuales/etc/cron.allow # Usuarios permitidos/etc/cron.deny # Usuarios denegados/var/log/cron # Logs de cron (RHEL/CentOS)/var/log/cron.log # Logs de cron (Ubuntu/Debian)Buenas Prácticas Finales
Section titled “Buenas Prácticas Finales”- Siempre usar rutas absolutas en scripts y comandos
- Configurar variables de entorno necesarias en crontab
- Implementar logging en todos los scripts importantes
- Verificar permisos de archivos y directorios
- Probar scripts manualmente antes de programarlos
- Configurar notificaciones para tareas críticas
- Mantener backups de configuraciones importantes
- Documentar el propósito de cada tarea programada
- Revisar regularmente logs y funcionamiento
- Implementar monitoreo de tareas críticas
Conclusión
Section titled “Conclusión”Cron es una herramienta fundamental en la administración de sistemas Linux. Su flexibilidad permite automatizar desde tareas simples hasta complejos sistemas de backup y monitoreo. La clave del éxito está en comprender su funcionamiento, implementar buenas prácticas de seguridad y mantener un monitoreo adecuado de las tareas programadas.
Este tutorial proporciona las bases necesarias para utilizar cron de manera efectiva y segura en entornos de producción. La automatización inteligente de tareas no solo mejora la eficiencia operativa, sino que también reduce la posibilidad de errores humanos y garantiza la consistencia en la ejecución de procesos críticos.
Autor: Tutorial de Cron para Linux Versión: 2.0 Fecha: 2024 Licencia: Creative Commons Attribution 4.0