6.4 Automatización de Tareas (Cron)
6.4 Automatización de Tareas (Cron) - Documentación Extendida
Sección titulada “6.4 Automatización de Tareas (Cron) - Documentación Extendida"- Fundamentos de la Automatización en Linux
- El Demonio Cron: Arquitectura y Funcionamiento
- La Sintaxis de los 5 Asteriscos
- Gestión Avanzada de Crontab
- Variables de Entorno y PATH en Cron
- Registro y Depuración de Tareas Cron
- Comandos Diferidos con At
- Systemd Timers: El Estándar Moderno
- Mejores Prácticas y Seguridad
- Casos de Uso y Ejemplos Prácticos
- Resolución de Problemas Comunes
1. Fundamentos de la Automatización en Linux
Sección titulada “1. Fundamentos de la Automatización en Linux"1.1 ¿Por qué automatizar?
Sección titulada “1.1 ¿Por qué automatizar?"La automatización de tareas es el pilar fundamental de la administración de sistemas moderna. Permite:
- Consistencia operativa: Ejecutar tareas siempre de la misma manera
- Eficiencia administrativa: Liberar tiempo del administrador
- Prevención de errores humanos: Eliminar la dependencia de acciones manuales
- Escalabilidad: Gestionar miles de sistemas con el mismo esfuerzo
1.2 Evolución histórica
Sección titulada “1.2 Evolución histórica"timeline
title Evolución de la Automatización en UNIX/Linux
1970s : Cron original (AT&T UNIX)
1980s : Vixie Cron (BSD)
1990s : Anacron (sistemas no 24/7)
2000s : Cronie (Red Hat)
2010s : Systemd Timers (estándar moderno)
2020s : Híbrido Cron/Systemd
2. El Demonio Cron: Arquitectura y Funcionamiento
Sección titulada “2. El Demonio Cron: Arquitectura y Funcionamiento"2.1 Arquitectura del Sistema Cron
Sección titulada “2.1 Arquitectura del Sistema Cron"# Estructura de archivos del sistema Cron/etc/cron.d/ # Archivos de configuración específicos/etc/cron.daily/ # Scripts ejecutados diariamente/etc/cron.hourly/ # Scripts ejecutados cada hora/etc/cron.monthly/ # Scripts ejecutados mensualmente/etc/cron.weekly/ # Scripts ejecutados semanalmente/etc/crontab # Archivo maestro de sistema/var/spool/cron/ # Directorio de crontabs de usuarios/var/log/syslog # Log de actividades del sistema2.2 Mecanismo de Ejecución
Sección titulada “2.2 Mecanismo de Ejecución"Ciclo de Vida de una Tarea Cron:
- Inicio del demonio:
cronse inicia durante el arranque del sistema - Lectura de archivos: Cada minuto, cron lee todos los archivos crontab
- Verificación temporal: Compara la hora actual con las programaciones
- Ejecución de tareas: Cuando coincide, ejecuta el comando especificado
- Registro de eventos: Guarda la ejecución en logs del sistema
# Verificar el estado del servicio cronsudo systemctl status cronsudo systemctl is-active cron
# Reiniciar cron después de cambiossudo systemctl restart cron
# Ver logs del sistema relacionados con cronsudo journalctl -u cron -f # Seguimiento en tiempo realsudo journalctl -u cron --since "2024-01-01"3. La Sintaxis de los 5 Asteriscos
Sección titulada “3. La Sintaxis de los 5 Asteriscos"3.1 Estructura Detallada
Sección titulada “3.1 Estructura Detallada"┌───────── Minuto (0-59)│ ┌─────── Hora (0-23)│ │ ┌───── Día del Mes (1-31)│ │ │ ┌─── Mes (1-12)│ │ │ │ ┌─ Día de la Semana (0-7, donde 0 y 7 = Domingo)│ │ │ │ │* * * * * COMANDO_A_EJECUTAR3.2 Operadores Especiales
Sección titulada “3.2 Operadores Especiales"| Operador | Significado | Ejemplo | Explicación |
|---|---|---|---|
* | Cualquier valor | * * * * * | Cada minuto |
, | Lista de valores | 1,15,30 * * * * | Minutos 1, 15 y 30 |
- | Rango de valores | 1-5 * * * * | De lunes a viernes |
/ | Paso/Intervalo | */15 * * * * | Cada 15 minutos |
0-23/2 | Cada 2 horas | 0 */2 * * * | A las 0,2,4,… horas |
3.3 Ejemplos Avanzados
Sección titulada “3.3 Ejemplos Avanzados"# Ejecutar cada 5 minutos entre las 9am y 5pm*/5 9-17 * * * /usr/bin/comando
# Ejecutar el primer día de cada mes a las 2:15am15 2 1 * * /usr/bin/comando
# Ejecutar cada hora exacta durante los fines de semana0 * * * 6,7 /usr/bin/comando
# Ejecutar cada 30 segundos (usando sleep en el comando)* * * * * /usr/bin/comando* * * * * sleep 30 && /usr/bin/comando3.4 Notaciones Especiales Predefinidas
Sección titulada “3.4 Notaciones Especiales Predefinidas"@reboot # Ejecutar al iniciar el sistema@daily # Una vez al día (equivalente a 0 0 * * *)@hourly # Una vez cada hora (0 * * * *)@weekly # Una vez a la semana (0 0 * * 0)@monthly # Una vez al mes (0 0 1 * *)@yearly # Una vez al año (0 0 1 1 *)4. Gestión Avanzada de Crontab
Sección titulada “4. Gestión Avanzada de Crontab"4.1 Comandos de Administración
Sección titulada “4.1 Comandos de Administración"# Editar crontab del usuario actualcrontab -e
# Editar crontab de usuario específicosudo crontab -e -u nombre_usuario
# Ver crontab del usuario actualcrontab -l
# Ver crontab de usuario específicosudo crontab -l -u nombre_usuario
# Eliminar crontab del usuario actualcrontab -r
# Eliminar crontab de usuario específicosudo crontab -r -u nombre_usuario4.2 Archivos de Crontab en /etc/cron.d/
Sección titulada “4.2 Archivos de Crontab en /etc/cron.d/"# Formato especial para archivos en /etc/cron.d/# Incluye el usuario que ejecutará el comando# MINUTO HORA DIA MES DIA_USUARIO USUARIO COMANDO
# Ejemplo: /etc/cron.d/backup0 2 * * * root /usr/local/bin/backup_sistema.sh15 4 * * 1-5 www-data /usr/bin/php /var/www/cron.php4.3 Buenas Prácticas en Crontab
Sección titulada “4.3 Buenas Prácticas en Crontab"# 1. Siempre usar rutas absolutas0 2 * * * /usr/bin/python3 /home/usuario/scripts/analisis.py
# 2. Definir variables de entorno al inicio# Ejemplo de cabecera recomendadaSHELL=/bin/bashPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binMAILTO=administrador@dominio.com
# 3. Usar scripts en lugar de comandos largos0 3 * * * /opt/scripts/mantenimiento_diario.sh
# 4. Redirigir salida para evitar logs innecesarios0 4 * * * /usr/bin/comando > /dev/null 2>&15. Variables de Entorno y PATH en Cron
Sección titulada “5. Variables de Entorno y PATH en Cron"5.1 El Problema del PATH en Cron
Sección titulada “5.1 El Problema del PATH en Cron"¿Por qué cron no encuentra mis comandos?
Cron ejecuta comandos en un entorno mínimo, sin cargar:
- Variables de entorno de usuario (
~/.bashrc,~/.profile) - Variables de entorno de sistema (
/etc/environment) - Alias de shell
- Funciones definidas en scripts de perfil
5.2 Soluciones para Problemas de PATH
Sección titulada “5.2 Soluciones para Problemas de PATH"# 1. Usar rutas absolutas en todos los comandos0 2 * * * /usr/bin/find /var/log -name "*.log" -mtime +30 -delete
# 2. Definir PATH dentro del crontabPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin0 2 * * * find /var/log -name "*.log" -mtime +30 -delete
# 3. Cargar entorno completo en el script#!/bin/bashsource /etc/profilesource $HOME/.bashrc# Resto del script...
# 4. Usar env para establecer variables0 2 * * * env PATH="/usr/local/bin:/usr/bin" /usr/bin/comando5.3 Variables Comunes en Crontab
Sección titulada “5.3 Variables Comunes en Crontab"# Variables más utilizadasMAILTO=admin@empresa.com # Donde enviar resultadosSHELL=/bin/bash # Shell a utilizarPATH=/usr/local/bin:/usr/bin:/binHOME=/home/usuario # Directorio homeLOGNAME=usuario # Nombre de usuario
# Ejemplo completoSHELL=/bin/bashPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binMAILTO=admin@empresa.comHOME=/home/admin
# Tareas programadas0 2 * * * /opt/scripts/backup.sh15 4 * * 1 /opt/scripts/reporte_semanal.sh6. Registro y Depuración de Tareas Cron
Sección titulada “6. Registro y Depuración de Tareas Cron"6.1 Logs del Sistema
Sección titulada “6.1 Logs del Sistema"# Ver logs de cronsudo grep CRON /var/log/syslogsudo journalctl -u cron
# Ver logs específicos por fechasudo journalctl -u cron --since "2024-01-01" --until "2024-01-31"
# Monitoreo en tiempo realsudo journalctl -u cron -fsudo tail -f /var/log/syslog | grep CRON6.2 Depuración de Tareas
Sección titulada “6.2 Depuración de Tareas"# 1. Registrar salida en archivo0 2 * * * /usr/bin/comando >> /var/log/comando.log 2>&1
# 2. Registrar con timestamp0 2 * * * echo "$(date): Ejecutando..." >> /var/log/comando.log && /usr/bin/comando >> /var/log/comando.log 2>&1
# 3. Probar comando manualmente# Ejecutar con el mismo entorno que cronenv -i /bin/bash -c 'PATH=/usr/local/bin:/usr/bin:/bin /usr/bin/comando'
# 4. Verificar sintaxis del crontab# No hay comando directo, pero se puede verificar manualmentecrontab -l | grep -v "^#" | awk 'NF>=6 {print}'6.3 Script de Diagnóstico
Sección titulada “6.3 Script de Diagnóstico"#!/bin/bashecho "=== DIAGNÓSTICO DE CRON ==="echo "1. Estado del servicio cron:"sudo systemctl status cron --no-pager
echo -e "\n2. Crontabs activos:"echo "--- Usuario actual ---"crontab -l 2>/dev/null || echo "No hay crontab configurado"echo "--- Root ---"sudo crontab -l 2>/dev/null || echo "No hay crontab de root"
echo -e "\n3. Archivos de cron:"ls -la /etc/cron.d/ 2>/dev/null || echo "No hay archivos en /etc/cron.d/"
echo -e "\n4. Últimas ejecuciones:"sudo journalctl -u cron --since "1 hour ago" | tail -10
echo -e "\n5. Permisos de scripts:"find /opt/scripts /usr/local/bin -name "*.sh" -exec ls -la {} \; 2>/dev/null7. Comandos Diferidos con At
Sección titulada “7. Comandos Diferidos con At"7.1 Instalación y Configuración
Sección titulada “7.1 Instalación y Configuración"# Instalación en Debian/Ubuntusudo apt-get updatesudo apt-get install at
# Instalación en RHEL/CentOSsudo yum install atsudo systemctl enable atdsudo systemctl start atd7.2 Sintaxis de At
Sección titulada “7.2 Sintaxis de At"# Formato básicoecho "comando" | at tiempo
# Ejemplos de tiemposat now + 5 minutes # Dentro de 5 minutosat now + 1 hour # Dentro de 1 horaat now + 2 days # Dentro de 2 díasat 3:00 PM tomorrow # Mañana a las 3 PMat 2:15 AM Friday # Viernes a las 2:15 AMat midnight # Medianoche de hoyat 10:00am 2025-12-25 # Fecha específicaat teatime # 4:00 PM7.3 Comandos Avanzados de At
Sección titulada “7.3 Comandos Avanzados de At"# Enviar comando complejoecho "/usr/bin/backup.sh --full /var/www" | at now + 30 minutes
# Usar archivo de comandosat -f script_completo.sh now + 1 hour
# Programar múltiples comandoscat << EOF | at now + 2 hoursecho "Iniciando mantenimiento"/opt/scripts/mantenimiento.shecho "Mantenimiento completado"EOF
# Ver cola de trabajosatq# oat -l
# Eliminar trabajo específicoatrm 1234
# Ver detalle de trabajoat -c 12347.4 Usos Prácticos de At
Sección titulada “7.4 Usos Prácticos de At"# 1. Reinicio programado después de actualizaciónecho "shutdown -r now" | at now + 15 minutes
# 2. Ejecutar tarea en horario no laboralecho "/opt/scripts/reporte_mensual.sh" | at 2:00 AM tomorrow
# 3. Eliminar archivos temporales mañanaecho "rm -rf /tmp/*" | at 6:00 AM tomorrow
# 4. Notificaciones programadasecho "echo 'Recordatorio: Reunión de equipo en 1 hora' | mail -s 'Recordatorio' usuario@empresa.com" | at now + 1 hour8. Systemd Timers: El Estándar Moderno
Sección titulada “8. Systemd Timers: El Estándar Moderno"8.1 Arquitectura de Systemd Timers
Sección titulada “8.1 Arquitectura de Systemd Timers"# Estructura de archivos/etc/systemd/system/├── backup.service # Servicio a ejecutar├── backup.timer # Timer que lo activa├── backup.timer.d/ # Overrides del timer│ └── override.conf└── timers.target.wants/ └── backup.timer -> /etc/systemd/system/backup.timer8.2 Creación de un Timer Systemd
Sección titulada “8.2 Creación de un Timer Systemd"Paso 1: Crear el servicio
[Unit]Description=Backup del sistemaAfter=network.target
[Service]Type=oneshotUser=rootGroup=rootExecStart=/usr/local/bin/backup_sistema.shStandardOutput=journalStandardError=journal
[Install]WantedBy=multi-user.targetPaso 2: Crear el timer
[Unit]Description=Timer para backup del sistemaRequires=backup.service
[Timer]# Programación equivalente a cronOnCalendar=daily # Diario# O específico: OnCalendar=*-*-* 02:00:00Persistent=true # Ejecutar si se perdió tiempo
# Configuración adicionalOnUnitActiveSec=24h # 24 horas después de última ejecuciónRandomizedDelaySec=5min # Evitar picos de carga
[Install]WantedBy=timers.target8.3 Sintaxis OnCalendar
Sección titulada “8.3 Sintaxis OnCalendar"# Especificaciones de tiempo en SystemdOnCalendar=*-*-* 00:00:00 # Cada medianocheOnCalendar=Mon..Fri 09:00:00 # Lunes a viernes a las 9 AMOnCalendar=*:0/15 # Cada 15 minutosOnCalendar=Sun *-*-* 02:00:00 # Domingos a las 2 AMOnCalendar=2024-01-01 # Fecha específica
# Rangos y listasOnCalendar=Mon..Wed,Sun *-*-* 00:00:00OnCalendar=*-*-01,15 00:00:00 # Días 1 y 15 de cada mes
# Intervalos relativosOnCalendar=2h # Cada 2 horasOnCalendar=30m # Cada 30 minutosOnCalendar=weekly # SemanalmenteOnCalendar=monthly # Mensualmente8.4 Gestión de Systemd Timers
Sección titulada “8.4 Gestión de Systemd Timers"# Habilitar y empezar el timersudo systemctl daemon-reloadsudo systemctl enable backup.timersudo systemctl start backup.timer
# Ver estadosudo systemctl status backup.timersudo systemctl list-timers # Listar todos los timerssudo systemctl list-timers --all # Incluyendo inactivos
# Información detalladasudo systemctl show backup.timersudo systemctl cat backup.timer
# Deshabilitar timersudo systemctl stop backup.timersudo systemctl disable backup.timer
# Ver ejecucionessudo journalctl -u backup.servicesudo journalctl -u backup.timer8.5 Ventajas de Systemd Timers sobre Cron
Sección titulada “8.5 Ventajas de Systemd Timers sobre Cron"| Aspecto | Cron | Systemd Timers |
|---|---|---|
| Logs | Dispersos, difíciles de seguir | Centralizados en journald |
| Dependencias | No soporta | Soporte nativo |
| Monitoreo | Manual | Integrado en systemd |
| Persistencia | No | Sí (ejecutar si se perdió) |
| Aleatorización | No | Sí (distribuir carga) |
| Seguridad | Básica | Namespaces, Capabilities |
| Paralelismo | Limitado | Control total |
9. Mejores Prácticas y Seguridad
Sección titulada “9. Mejores Prácticas y Seguridad"9.1 Seguridad en Cron
Sección titulada “9.1 Seguridad en Cron"# Control de acceso# Permitir uso solo a usuarios listadosusuario1usuario2
# Denegar uso a usuarios listados# /etc/cron.denyusuario_no_autorizado
# Permisos de scriptssudo chown root:root /opt/scripts/script.shsudo chmod 700 /opt/scripts/script.sh9.2 Buenas Prácticas Generales
Sección titulada “9.2 Buenas Prácticas Generales"# 1. Siempre respaldar crontab antes de editarcrontab -l > backup_cron_$(date +%Y%m%d).txt
# 2. Usar control de versiones para scriptscd /opt/scriptsgit initgit add .git commit -m "Versión inicial de scripts cron"
# 3. Validar scripts antes de programarlosbash -n script.sh # Verificar sintaxisbash -x script.sh # Debug ejecución
# 4. Monitoreo proactivo0 0 * * * /usr/bin/test -e /var/log/comando.log && echo "OK" || echo "ERROR" | mail -s "Alerta Cron" admin@empresa.com
# 5. Documentación en el propio crontab# Backup diario - Ejecutado a las 2:00 AM0 2 * * * /opt/scripts/backup.sh9.3 Plantilla de Crontab Estándar
Sección titulada “9.3 Plantilla de Crontab Estándar"# ============================================# Crontab para servidor web - user: www-data# Fecha: $(date +%Y-%m-%d)# Responsable: Administrador# ============================================
# Variables de entornoSHELL=/bin/bashPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binMAILTO=admin@empresa.comHOME=/var/www
# Logs de aplicación - Rotación diaria a las 2:00 AM0 2 * * * /usr/sbin/logrotate /etc/logrotate.d/aplicacion
# Backup de base de datos - Diario a las 3:00 AM0 3 * * * /opt/scripts/backup_mysql.sh
# Limpieza de caché - Cada hora0 * * * * /usr/bin/php /var/www/app/console cache:clear --env=prod
# Reportes - Lunes a viernes a las 8:00 AM0 8 * * 1-5 /opt/scripts/generar_reportes.sh
# Mantenimiento semanal - Domingo a las 4:00 AM0 4 * * 0 /opt/scripts/mantenimiento_semanal.sh10. Casos de Uso y Ejemplos Prácticos
Sección titulada “10. Casos de Uso y Ejemplos Prácticos"10.1 Backup Automatizado
Sección titulada “10.1 Backup Automatizado"#!/bin/bash# Backup completo con rotación
BACKUP_DIR="/backup"DATE=$(date +%Y%m%d_%H%M%S)RETENTION_DAYS=30
# Crear backup comprimidotar -czf ${BACKUP_DIR}/backup_${DATE}.tar.gz \ /etc \ /var/www \ /opt/aplicacion \ /home 2>/dev/null
# Eliminar backups antiguosfind ${BACKUP_DIR} -name "backup_*.tar.gz" -mtime +${RETENTION_DAYS} -delete
# Registrar en logecho "$(date): Backup completado - ${BACKUP_DIR}/backup_${DATE}.tar.gz" >> /var/log/backup.log
# Notificar por emailecho "Backup completado exitosamente" | mail -s "Backup Diario - $(hostname)" admin@empresa.com
# Ejecutar a las 2:00 AM diario0 2 * * * /opt/scripts/backup_completo.sh10.2 Monitoreo de Sistema
Sección titulada “10.2 Monitoreo de Sistema"#!/bin/bash# Monitoreo de recursos del sistema
ALERT_CPU=90ALERT_MEM=90ALERT_DISK=85EMAIL="alertas@empresa.com"
# CPUCPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d. -f1)if [ $CPU_USAGE -gt $ALERT_CPU ]; then echo "ALERTA: CPU al ${CPU_USAGE}%" | mail -s "Alerta CPU - $(hostname)" $EMAILfi
# MemoriaMEM_USAGE=$(free | grep Mem | awk '{printf("%.0f", $3/$2 * 100)}')if [ $MEM_USAGE -gt $ALERT_MEM ]; then echo "ALERTA: Memoria al ${MEM_USAGE}%" | mail -s "Alerta Memoria - $(hostname)" $EMAILfi
# DiscoDISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | cut -d% -f1)if [ $DISK_USAGE -gt $ALERT_DISK ]; then echo "ALERTA: Disco al ${DISK_USAGE}%" | mail -s "Alerta Disco - $(hostname)" $EMAILfi
# Ejecutar cada 15 minutos*/15 * * * * /opt/scripts/monitoreo_sistema.sh10.3 Automatización de Reportes
Sección titulada “10.3 Automatización de Reportes"#!/bin/bash# Generación de reporte de vacaciones
REPORT_DIR="/var/www/reports"DATE=$(date +%Y%m%d)
# Generar reporte/usr/bin/mysql -u usuario -pcontraseña -D empresa -e "SELECT nombre, apellido, fecha_inicio, fecha_finFROM empleadosWHERE estado = 'vacaciones'ORDER BY fecha_inicio" > ${REPORT_DIR}/vacaciones_${DATE}.csv
# Comprimirgzip ${REPORT_DIR}/vacaciones_${DATE}.csv
# Enviar por emailecho "Reporte de vacaciones generado" | \mail -s "Reporte Vacaciones ${DATE}" -a ${REPORT_DIR}/vacaciones_${DATE}.csv.gz \director@empresa.com
# Ejecutar todos los lunes a las 8:00 AM0 8 * * 1 /opt/scripts/reporte_vacaciones.sh10.4 Mantenimiento de Sistema
Sección titulada “10.4 Mantenimiento de Sistema"#!/bin/bash# Mantenimiento completo de sistema
LOG_FILE="/var/log/mantenimiento.log"DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[${DATE}] Iniciando mantenimiento..." >> ${LOG_FILE}
# 1. Limpiar paquetes no necesariosapt-get autoremove -y >> ${LOG_FILE} 2>&1apt-get autoclean >> ${LOG_FILE} 2>&1
# 2. Vaciar logs viejosfind /var/log -type f -name "*.log" -mtime +7 -deletefind /var/log -type f -name "*.gz" -mtime +30 -delete
# 3. Actualizar caché de paquetesapt-get update >> ${LOG_FILE} 2>&1
# 4. Verificar integridad de paquetesdpkg --verify >> ${LOG_FILE} 2>&1
# 5. Limpiar directorios temporalesrm -rf /tmp/* 2>/dev/nullrm -rf /var/tmp/* 2>/dev/null
# 6. Verificar sistema de archivosfsck -n /dev/sda1 >> ${LOG_FILE} 2>&1
# 7. Reiniciar servicios problemáticossystemctl restart apache2 2>/dev/nullsystemctl restart mysql 2>/dev/null
echo "[${DATE}] Mantenimiento completado." >> ${LOG_FILE}
# Ejecutar cada domingo a las 3:00 AM0 3 * * 0 /opt/scripts/mantenimiento_sistema.sh11. Resolución de Problemas Comunes
Sección titulada “11. Resolución de Problemas Comunes"11.1 Checklist de Diagnóstico
Sección titulada “11.1 Checklist de Diagnóstico"# 1. Verificar que cron esté ejecutándosepgrep cron | wc -lsystemctl status cron | grep "active (running)"
# 2. Verificar permisos del scriptls -la /opt/scripts/mi_script.sh# Debería tener permisos de ejecución: -rwxr-xr-x
# 3. Verificar que el comando existe en el PATH de cronwhich mi_comando# Si no está en PATH, usar ruta absoluta
# 4. Verificar que el script funciona manualmente/opt/scripts/mi_script.sh# Debería ejecutarse sin errores
# 5. Verificar sintaxis del crontabcrontab -l | grep -v "^#" | awk 'NF>=6 {print}'
# 6. Verificar logs de cronsudo journalctl -u cron --since "1 hour ago" | grep -i errorsudo grep -i error /var/log/syslog | grep CRON11.2 Problemas Comunes y Soluciones
Sección titulada “11.2 Problemas Comunes y Soluciones"Problema 1: El comando funciona manualmente pero no en cron
Sección titulada “Problema 1: El comando funciona manualmente pero no en cron"# Causa: PATH diferente# Solución 1: Usar ruta absolutawhich comando # Encontrar ruta0 2 * * * /usr/bin/comando argumentos
# Solución 2: Definir PATH en crontabPATH=/usr/local/bin:/usr/bin:/bin0 2 * * * comando argumentos
# Solución 3: Usar entorno completo en script#!/bin/bashsource /etc/profilesource $HOME/.bashrcProblema 2: Script ejecuta pero no produce resultados
Sección titulada “Problema 2: Script ejecuta pero no produce resultados"# Solución: Redirigir salida para depuración0 2 * * * /opt/scripts/script.sh >> /tmp/script_debug.log 2>&1
# Ver archivo después de ejecucióncat /tmp/script_debug.log
# Asegurar que el directorio de output existe y tiene permisosmkdir -p /var/log/mi_appchmod 755 /var/log/mi_appProblema 3: Múltiples instancias ejecutándose simultáneamente
Sección titulada “Problema 3: Múltiples instancias ejecutándose simultáneamente"# Solución: Usar bloqueo de archivo#!/bin/bashLOCK_FILE="/var/lock/mi_script.lock"
if [ -f "$LOCK_FILE" ]; then echo "Script ya está ejecutándose" exit 1fi
touch $LOCK_FILE
# ... código del script ...
rm $LOCK_FILEProblema 4: Correo de cron no se envía
Sección titulada “Problema 4: Correo de cron no se envía"# 1. Verificar que postfix/ssmtp esté configuradodpkg -l | grep postfixsystemctl status postfix
# 2. Configurar MAILTO en crontabMAILTO=admin@empresa.com
# 3. Redirigir a archivo en lugar de email0 2 * * * /opt/scripts/script.sh > /dev/null 2>&111.3 Script de Monitoreo de Tareas
Sección titulada “11.3 Script de Monitoreo de Tareas"#!/bin/bash# Monitoreo de tareas críticas
LOG_FILE="/var/log/monitor_cron.log"EMAIL="admin@empresa.com"
check_task() { local task_name=$1 local expected_time=$2 local max_delay_minutes=$3
# Buscar en logs la última ejecución last_run=$(sudo journalctl -u cron --since "${expected_time}" | \ grep "$task_name" | tail -1 | awk '{print $1, $2, $3}')
if [ -z "$last_run" ]; then echo "ALERTA: Tarea $task_name no ejecutada en $expected_time" >> $LOG_FILE echo "Tarea $task_name no ejecutada" | mail -s "Alerta Cron" $EMAIL fi}
# Verificar tareas críticascheck_task "backup_sistema" "2:00:00" 30check_task "reporte_diario" "8:00:00" 15
# Ejecutar cada hora0 * * * * /opt/scripts/monitor_cron.shRecursos Adicionales
Sección titulada “Recursos Adicionales"Documentación Oficial
Sección titulada “Documentación Oficial"man cron,man crontab,man atman systemd.timer,man systemd.time- Arch Linux Cron Documentation
- Systemd Timers Documentation
Herramientas Útiles
Sección titulada “Herramientas Útiles"- Crontab Guru: Generador de sintaxis cron (https://crontab.guru/)
- Crontab Generator: (https://crontab-generator.org/)
- Systemd Timer Generator: (https://www.systutorials.com/systemd-timer-syntax/)
Plantillas de Respuesta Rápida
Sección titulada “Plantillas de Respuesta Rápida"# Respaldo de crontabcrontab -l > cron_backup_$(date +%Y%m%d).txt
# Restaurar crontabcrontab cron_backup_20240101.txt
# Verificar sintaxis de croncrontab -e # No hay check directo, usar cuidado
# Forzar ejecución de tarea ahora/usr/bin/comando &# O para scripts de cron/opt/scripts/mi_script.sh
# Ver últimas ejecucionessudo journalctl -u cron --since "1 hour ago" | tail -20¡Ah, perfecto! Ahora entiendo. Quieres que desarrolle y amplíe los ejercicios de Multiple Choice que ya estaban en la documentación original, haciendo que sean más detallados, educativos y con explicaciones más profundas. Vamos a ello:
12. Comprueba tus Conocimientos - Multiple Choice Extendido
Sección titulada “12. Comprueba tus Conocimientos - Multiple Choice Extendido"Pregunta 1: Sintaxis Cron para Días Laborables
Sección titulada “Pregunta 1: Sintaxis Cron para Días Laborables"Escenario: Tu superior quiere que los servidores generen y procesen un recibo matemático que solo y exclusivamente corra todos los días laborales (De Lunes a Viernes) a las 08:15 AM de la mañana.
¿Cuál es la sintaxis ruda y milimétrica que debes meter en el crontab -e oficial de Root para lograr esto?
Explicación Detallada:
Sección titulada “Explicación Detallada:"Análisis de la Sintaxis Correcta: 15 08 * * 1-5 /opt/generar_recibo.sh
Vamos a desglosar cada campo:
MINUTO HORA DIA_MES MES DIA_SEMANA COMANDO 15 08 * * 1-5 /opt/generar_recibo.sh| Campo | Valor | Significado |
|---|---|---|
| Minuto | 15 | Exactamente en el minuto 15 |
| Hora | 08 | A las 8 de la mañana (formato 24h) |
| Día del Mes | * | Cualquier día del mes |
| Mes | * | Cualquier mes del año |
| Día de Semana | 1-5 | De lunes (1) a viernes (5) |
| Comando | /opt/generar_recibo.sh | Ruta absoluta al script |
¿Por qué fallan las otras opciones?
Opción 1: 8 15 * * 1-5 /opt/generar_recibo.sh
- ❌ Error: Los campos están invertidos
8en la posición de minuto significa “minuto 8”15en la posición de hora significa “15:00” (3 PM)- El resultado sería: ejecutar a las 15:08 (3:08 PM), no a las 08:15 AM
Opción 3: * * 15 08 1-5 /opt/generar_recibo.sh
- ❌ Error: Confusión total de campos
* *significa “cada minuto de cada hora”15en día del mes = solo el día 15 de cada mes08en mes = solo en agosto- Resultado: Ejecutaría cada minuto del día 15 de agosto, solo si es lunes-viernes
Regla Nemotécnica para Recordar:
“Mi Hora Debe ser Muy Día” (Minuto, Hora, Día, Mes, DíaSemana)
Ejemplo Adicional para Practicar:
# ¿Qué significa esta línea?30 14 * * 1-5 /usr/bin/reporte.sh# Respuesta: Ejecuta reporte.sh a las 14:30 (2:30 PM) de lunes a viernesPregunta 2: El Poder del Comando at en Situaciones Críticas
Sección titulada “Pregunta 2: El Poder del Comando at en Situaciones Críticas"Escenario: Acabas de cometer un error desastroso en un switch de red de una sucursal en Francia dejándola aislada de tu nube porque le cambiaste la IP. Recuerdas, sudando una lágrima de sudor frío, que esto te pasaría y hace 10 minutos (antes del fallo) creaste la orden aplazada mágica echo "/sbin/reboot" | at now + 30 minutes. Acabas de cortarte las manos pero todavía puedes esperar.
¿Qué sucederá gracias al comando at en 20 frenéticos y largos minutos?
Explicación Detallada:
Sección titulada “Explicación Detallada:"¿Qué es at y cómo funciona?
at es un sistema de cola de trabajos que ejecuta comandos una sola vez en un momento específico. A diferencia de cron, que es para tareas repetitivas, at es para “bombas de tiempo” controladas.
Características Clave de at:
- Independencia de red: Una vez programado, el trabajo se guarda en disco
- Persistencia: Sobrevive a reinicios del sistema
- Aislamiento: Se ejecuta en su propio entorno, sin necesidad de conexión
¿Por qué la Opción 1 es incorrecta?
- ❌ El demonio
atdno “muere” por problemas de red - ❌ Los trabajos de
atse almacenan en/var/spool/atjobs/como archivos - ❌ La desconexión de red no afecta al temporizador interno del sistema
¿Por qué la Opción 3 es incorrecta?
- ❌
atno depende de systemd logging para ejecutarse - ❌ El comando
rebootse ejecutará independientemente del estado de los logs - ❌ Aunque no puedas ver los logs, el reinicio ocurrirá
Arquitectura de at en Detalle:
# 1. Cuando programas un trabajo con at:echo "/sbin/reboot" | at now + 30 minutes
# 2. El sistema hace esto:# - Crea un archivo en /var/spool/atjobs/# - Guarda el comando y el tiempo de ejecución# - El demonio atd verifica este directorio cada minuto
# 3. Cuando llega el momento:# - atd ejecuta el comando con los mismos permisos del usuario que lo programó# - El comando se ejecuta en un entorno mínimo pero completo
# 4. Verificación de trabajos pendientes:atq # Lista trabajos en colaatrm 1234 # Eliminar trabajo específicoat -c 1234 # Ver contenido del trabajoCaso Práctico: El Escenario del Switch Francés
# 1. Antes de hacer cambios peligrosos (ESTRATEGIA DE SEGURIDAD)echo "/sbin/reboot" | at now + 30 minutes
# 2. Realizas cambios arriesgados# ... (cambias IP, tocas configuraciones)
# 3. Si todo falla, en 30 minutos:# - El sistema se reinicia automáticamente# - Vuelve a la configuración guardada en disco# - Recuperas acceso remoto
# 4. Si todo sale bien (antes de los 30 min):atq # Ver ID del trabajoatrm <ID> # Cancelar el reinicio programadoMejores Prácticas con at:
- Siempre programar un “escape” antes de cambios críticos
- Usar
atqpara verificar trabajos pendientes - Documentar el ID del trabajo por si necesitas cancelarlo
- Programar con margen suficiente (30-60 minutos para reacción)
Pregunta 3: El Error Clásico del PATH en Cron
Sección titulada “Pregunta 3: El Error Clásico del PATH en Cron"Escenario: Un empleado Junior de tu equipo se queja histérico diciendo: “Programé perfectamente el script en /home/junior/bash.sh en el root de Cron tirando crontab -e. Le puse los 5 asteriscos así que sé que se corre cada minuto. El script echa humo a mano borrando /tmp/ basuras, pero por CRON la carpeta /tmp se me llena por las noches!”. Chequeas su sintaxis de ejecución escrita al final del asterisco y descubres un error mortal común Sysadmin.
¿Qué fallo arruinó al Junior?
Explicación Detallada:
Sección titulada “Explicación Detallada:"El Problema Fundamental: Entorno de Ejecución de Cron
# El Script del Junior (con ERROR):#!/bin/bash# /home/junior/bash.sh - ¡ESTE SCRIPT FALLA EN CRON!
rm -rf /tmp/*.tmp # ← ERROR: usa 'rm' sin ruta absolutafind /tmp -name "*.log" -mtime +7 -delete # ← ERROR: 'find' sin rutatar -czf backup.tar.gz /var/log # ← ERROR: 'tar' sin ruta¿Qué pasa cuando Cron ejecuta esto?
- Cron usa un PATH mínimo (normalmente
/usr/bin:/bin) - No carga
.bashrc,.profileo/etc/profile - No tiene alias ni funciones definidas
- El directorio de trabajo es el HOME del usuario o
/
Comparativa de Entornos:
| Aspecto | Terminal Interactiva | Cron |
|---|---|---|
| PATH | Completo (~80+ rutas) | Mínimo (~2-3 rutas) |
| Variables | Todas las del usuario | Solo las definidas |
| Alias | Cargados | No disponibles |
| Funciones | Definidas | No disponibles |
| Working Directory | Donde estés | HOME o / |
Solución Correcta para el Script:
#!/bin/bash# /home/junior/bash.sh - VERSIÓN CORREGIDA
# 1. Definir PATH explícitamentePATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# 2. O usar rutas absolutas en cada comando/bin/rm -rf /tmp/*.tmp/usr/bin/find /tmp -name "*.log" -mtime +7 -delete/bin/tar -czf /backup/backup.tar.gz /var/log
# 3. Asegurar directorio de trabajocd /home/junior || exit 1
# 4. Redirigir salida para depuraciónexec > /var/log/bash_script.log 2>&1
# 5. Ahora el script funciona en cronCómo Depurar Problemas de PATH:
# 1. Ver qué PATH usa cron realmente* * * * * echo $PATH > /tmp/cron_path.txt
# 2. Ver dónde están tus comandoswhich rm # Muestra: /bin/rmwhich find # Muestra: /usr/bin/findwhich tar # Muestra: /bin/tar
# 3. Probar script en entorno cronenv -i /bin/bash --noprofile --norc -c 'PATH=/usr/bin:/bin /home/junior/bash.sh'
# 4. Ver logs de errorsudo journalctl -u cron | grep -i "bash.sh"El Error en el Crontab del Junior:
# ❌ MAL - Usa nombres simples* * * * * /home/junior/bash.sh
# ✅ BIEN - Define PATH en el crontabSHELL=/bin/bashPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin* * * * * /home/junior/bash.sh
# ✅ MEJOR - Usa rutas absolutas en el comando* * * * * /bin/bash /home/junior/bash.sh
# ✅ ÓPTIMO - Combina todoSHELL=/bin/bashPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin* * * * * /home/junior/bash.sh >> /var/log/bash_script.log 2>&1Ejemplo Práctico de Error Común:
# Script que funciona en terminal pero falla en cron#!/bin/bash# PROBLEMA: depende de variables de entorno
echo "Iniciando backup..." > /var/log/backup.log # ERROR: puede no tener permisostar -czf backup.tar.gz /etc # ERROR: 'tar' puede no estar en PATHmysql -u root -p$PASS db < backup.sql # ERROR: $PASS no existe en cron
# SOLUCIÓN:#!/bin/bashexport PATH=/usr/local/bin:/usr/bin:/binexport BACKUP_DIR=/backupexport LOG_FILE=/var/log/backup.log
mkdir -p $BACKUP_DIR 2>/dev/null/usr/bin/tar -czf $BACKUP_DIR/backup_$(date +%Y%m%d).tar.gz /etc/usr/bin/mysql -u root -p"$DB_PASS" db < /backup/backup.sqlEstadísticas de Errores Comunes en Cron:
| Error | Frecuencia | Solución |
|---|---|---|
| PATH incompleto | 65% | Usar rutas absolutas |
| Variables no definidas | 20% | Definir en crontab o script |
| Permisos de archivo | 10% | Verificar permisos |
| Directorio de trabajo | 5% | Usar cd o rutas absolutas |
Resumen de Conceptos Clave para Multiple Choice
Sección titulada “Resumen de Conceptos Clave para Multiple Choice"Para Recordar sobre Cron:
Sección titulada “Para Recordar sobre Cron:"- Orden de campos: Minuto, Hora, Día, Mes, DíaSemana
- Rangos:
1-5= Lunes a Viernes,0o7= Domingo - Siempre usar rutas absolutas en comandos y scripts
- Definir PATH en el crontab o usar
/usr/bin/comando - Redirigir salida para depuración:
>> /var/log/script.log 2>&1
Para Recordar sobre At:
Sección titulada “Para Recordar sobre At:"- Una sola ejecución (no repetitiva)
- Persiste aunque se caiga la red
- Útil para “escape” en cambios críticos
- Comandos útiles:
atq,atrm,at -c - Formato:
echo "comando" | at tiempo
Checklist de Depuración:
Sección titulada “Checklist de Depuración:"- [ ] ¿El script funciona manualmente?
- [ ] ¿El script tiene permisos de ejecución?
- [ ] ¿Usa rutas absolutas?
- [ ] ¿Define PATH o usa comandos con ruta completa?
- [ ] ¿Tiene el script los permisos adecuados?
- [ ] ¿Está el servicio cron ejecutándose?
- [ ] ¿Hay errores en los logs de cron?