Skip to content

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.

  • 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
  • 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

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 es tanto el comando utilizado para editar las tareas programadas como el archivo que contiene estas tareas. Existen diferentes tipos:

  1. Crontab de usuario: ~/.crontab o /var/spool/cron/crontabs/usuario
  2. Crontab del sistema: /etc/crontab
  3. Directorios del sistema: /etc/cron.d/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/
Terminal window
# Verificar el estado del servicio cron
sudo systemctl status cron
# En sistemas con crond
sudo systemctl status crond
# Verificar si el proceso está corriendo
ps aux | grep cron
Terminal window
# Ubuntu/Debian
sudo apt update
sudo apt install cron
# RHEL/CentOS/Fedora
sudo yum install cronie
# o en versiones más nuevas
sudo dnf install cronie
# Arch Linux
sudo pacman -S cronie
Terminal window
# Habilitar cron para que se inicie automáticamente
sudo systemctl enable cron
sudo systemctl start cron
# Para crond
sudo systemctl enable crond
sudo systemctl start crond
* * * * * 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)
CampoRangoDescripción
Minuto0-59Minuto específico de la hora
Hora0-23Hora en formato 24h
Día del mes1-31Día específico del mes
Mes1-12 o JAN-DECMes del año
Día de la semana0-6 o SUN-SATDía de la semana (0 y 7 = Domingo)
SímboloSignificadoEjemplo
*Todos los valores* * * * * = cada minuto
,Separar múltiples valores0,15,30,45 = minutos 0, 15, 30, 45
-Rango de valores1-5 = lunes a viernes
/Intervalos (step)*/10 = cada 10 unidades
LÚltimo (día del mes/semana)L = último día del mes
WDía laboral más cercano15W = día laboral más cercano al 15
#N-ésima ocurrenciaMON#2 = segundo lunes del mes
?No especificar valorUsado 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/

Terminal window
# Editar crontab del usuario actual
crontab -e
# Listar tareas del usuario actual
crontab -l
# Eliminar todas las tareas del usuario actual
crontab -r
# Eliminar con confirmación
crontab -i -r
# Ver la fecha de última modificación
crontab -v

Gestión de Crontabs de Otros Usuarios (como root)

Section titled “Gestión de Crontabs de Otros Usuarios (como root)”
Terminal window
# Editar crontab de un usuario específico
sudo crontab -u usuario -e
# Listar tareas de un usuario específico
sudo crontab -u usuario -l
# Eliminar crontab de un usuario específico
sudo crontab -u usuario -r
Terminal window
# Exportar crontab a un archivo
crontab -l > mi_crontab_backup.txt
# Importar crontab desde un archivo
crontab mi_crontab_backup.txt
# Agregar tareas manteniendo las existentes
crontab -l > temp_crontab
echo "0 2 * * * /ruta/al/script.sh" >> temp_crontab
crontab temp_crontab
rm temp_crontab

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”
Terminal window
# Abrir crontab para editar
crontab -e
# Agregar variables al inicio del archivo
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com
HOME=/home/usuario
LANG=es_ES.UTF-8
# Luego agregar las tareas
0 2 * * * /ruta/al/script.sh
/home/usuario/scripts/wrapper.sh
#!/bin/bash
source /home/usuario/.bashrc
source /home/usuario/.bash_profile
/ruta/al/script_principal.sh
# En crontab
0 2 * * * /home/usuario/scripts/wrapper.sh
Terminal window
# En crontab
BASH_ENV=/etc/profile
0 2 * * * /ruta/al/script.sh
VariableDescripciónEjemplo
SHELLShell utilizado para ejecutar comandosSHELL=/bin/bash
PATHRutas donde buscar ejecutablesPATH=/usr/local/bin:/usr/bin:/bin
MAILTOEmail para enviar salida de comandosMAILTO=admin@example.com
HOMEDirectorio home del usuarioHOME=/home/usuario
LOGNAMENombre del usuarioLOGNAME=usuario
USERNombre del usuarioUSER=usuario
Terminal window
# Crear una tarea que exporte todas las variables
* * * * * env > /tmp/cron-env.log
# Comparar con el entorno del shell
env > /tmp/shell-env.log
diff /tmp/cron-env.log /tmp/shell-env.log
Terminal window
# Ejecutar cada minuto
* * * * * /ruta/al/script.sh
# Ejecutar cada hora en punto
0 * * * * /ruta/al/script.sh
# Ejecutar diariamente a las 2:30 AM
30 2 * * * /ruta/al/script.sh
# Ejecutar semanalmente los domingos a las 3:00 AM
0 3 * * 0 /ruta/al/script.sh
# Ejecutar mensualmente el día 1 a las 4:00 AM
0 4 1 * * /ruta/al/script.sh
Terminal window
# Cada 5 minutos
*/5 * * * * /ruta/al/script.sh
# Cada 2 horas
0 */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 PM
0 9-17 * * 1-5 /ruta/al/script.sh
Terminal window
# Ejecutar a las 8:30 AM y 6:30 PM todos los días
30 8,18 * * * /ruta/al/script.sh
# Ejecutar lunes, miércoles y viernes a las 2:15 PM
15 14 * * 1,3,5 /ruta/al/script.sh
# Ejecutar los días 1 y 15 de cada mes
0 0 1,15 * * /ruta/al/script.sh
Terminal window
# 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 diciembre
0 2 * 1-11 0 /usr/local/bin/backup.sh
# Mantenimiento el primer lunes de cada mes
0 3 1-7 * 1 /usr/local/bin/maintenance.sh
# Limpeza de logs diaria, pero duplicada los viernes para limpieza profunda
0 2 * * * /usr/local/bin/cleanup-daily.sh
0 3 * * 5 /usr/local/bin/cleanup-deep.sh
Terminal window
# Redirigir salida a un archivo
0 2 * * * /ruta/al/script.sh >> /var/log/script.log 2>&1
# Separar stdout y stderr
0 2 * * * /ruta/al/script.sh >> /var/log/script.log 2>> /var/log/script-error.log
# Descartar toda salida
0 2 * * * /ruta/al/script.sh > /dev/null 2>&1
# Enviar solo errores por email (manteniendo MAILTO configurado)
0 2 * * * /ruta/al/script.sh > /dev/null
Terminal window
# 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)
Terminal window
# Editar configuración de rsyslog
sudo vi /etc/rsyslog.conf
# Agregar o descomentar la línea:
cron.* /var/log/cron.log
# Reiniciar rsyslog
sudo systemctl restart rsyslog
Terminal window
# Ver logs de cron con journalctl
journalctl -u cron
# Logs en tiempo real
journalctl -u cron -f
# Logs de un período específico
journalctl -u cron --since "2024-01-01" --until "2024-01-02"
# Logs con mayor detalle
journalctl -u cron -n 50 --no-pager
Terminal window
# Ver ejecuciones recientes de cron
grep CRON /var/log/syslog | tail -20
# Buscar errores en logs de cron
grep -i "error\|failed" /var/log/cron
# Filtrar por usuario específico
grep "usuario" /var/log/cron
# Filtrar por comando específico
grep "backup.sh" /var/log/cron
# Ver logs de hoy
grep "$(date +%b\ %d)" /var/log/cron
/usr/local/bin/mi_script.sh
#!/bin/bash
LOG_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_FILE
else
echo "[$DATE] ERROR: Script falló" >> $LOG_FILE
exit 1
fi
echo "[$DATE] Script finalizado" >> $LOG_FILE

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:

Terminal window
# Comparar entornos
# En cron:
* * * * * env > /tmp/cron-env.log
# En terminal:
env > /tmp/shell-env.log
diff /tmp/cron-env.log /tmp/shell-env.log
# Usar rutas absolutas
* * * * * /usr/bin/python3 /home/usuario/script.py
# Definir PATH completo
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
* * * * * python3 /home/usuario/script.py

Solución:

Terminal window
# Verificar permisos del script
ls -la /ruta/al/script.sh
# Dar permisos de ejecución
chmod +x /ruta/al/script.sh
# Verificar que el usuario puede ejecutar el script
sudo -u usuario /ruta/al/script.sh

Solución:

Terminal window
# Encontrar la ruta completa de un comando
which comando
whereis comando
# Usar rutas absolutas en el script
#!/bin/bash
/usr/bin/rsync -av /origen/ /destino/
/bin/echo "Backup completado" >> /var/log/backup.log

Solución:

wrapper.sh
# Crear script wrapper que cargue el entorno
#!/bin/bash
source ~/.bashrc
source ~/.profile
/ruta/al/script/original.sh
# En crontab
0 2 * * * /ruta/al/wrapper.sh
# Crear un script de prueba
#!/bin/bash
echo "=== Inicio del script: $(date) ==="
echo "Usuario: $(whoami)"
echo "Directorio actual: $(pwd)"
echo "PATH: $PATH"
env | sort
echo "=== 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>&1
Terminal window
# Ejecutar comando con entorno mínimo como cron
env -i HOME=/home/usuario PATH=/usr/bin:/bin bash -c '/ruta/al/script.sh'
# Probar con el mismo usuario que ejecutará cron
sudo -u usuario env -i HOME=/home/usuario PATH=/usr/bin:/bin /ruta/al/script.sh
# Usar herramientas online como crontab.guru
# O crear un script de verificación
#!/bin/bash
# Verificar que cron esté corriendo
systemctl is-active cron
# Listar trabajos actuales
crontab -l
# Verificar logs recientes
tail -f /var/log/cron
#!/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-pager
echo
echo "2. Cron está corriendo:"
pgrep cron
echo
echo "3. Tareas programadas del usuario actual:"
crontab -l
echo
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 ejecute
cat /tmp/cron_env_check
rm /tmp/cron_env_check
# Remover la tarea temporal
crontab -l | grep -v "env > /tmp/cron_env_check" | crontab -
echo
echo "5. Logs recientes de cron:"
tail -20 /var/log/syslog | grep CRON
echo
echo "6. Permisos de directorio de cron:"
ls -la /var/spool/cron/crontabs/
echo
echo "=== FIN DEL DIAGNÓSTICO ==="
Terminal window
# Permisos recomendados para scripts
chmod 750 /ruta/al/script.sh # rwxr-x---
chown usuario:grupo /ruta/al/script.sh
# Verificar permisos de archivos crontab
ls -la /var/spool/cron/crontabs/
# Los archivos crontab deben tener permisos 600
chmod 600 /var/spool/cron/crontabs/usuario
Terminal window
# Permitir solo usuarios específicos
echo "usuario1" >> /etc/cron.allow
echo "usuario2" >> /etc/cron.allow
# Denegar usuarios específicos
echo "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 cron

3. Evitar Información Sensible en Crontab

Section titled “3. Evitar Información Sensible en Crontab”
Terminal window
# MALO: contraseñas en línea de comandos
0 2 * * * mysqldump -u root -pmysecretpass database > backup.sql
# BUENO: usar archivos de configuración
0 2 * * * mysqldump --defaults-file=/etc/mysql/backup.cnf database > backup.sql
# BUENO: usar variables de entorno
DB_PASSWORD=mysecretpass
0 2 * * * mysqldump -u root -p$DB_PASSWORD database > backup.sql
#!/bin/bash
# Script con validaciones de seguridad
# Verificar que el script se ejecuta como el usuario correcto
if [[ "$(whoami)" != "expected_user" ]]; then
echo "ERROR: Script debe ejecutarse como expected_user"
exit 1
fi
# Validar que los directorios existen
SOURCE_DIR="/path/to/source"
DEST_DIR="/path/to/destination"
if [[ ! -d "$SOURCE_DIR" ]]; then
echo "ERROR: Directorio fuente no existe: $SOURCE_DIR"
exit 1
fi
if [[ ! -d "$DEST_DIR" ]]; then
echo "ERROR: Directorio destino no existe: $DEST_DIR"
exit 1
fi
# Usar rutas absolutas
/usr/bin/rsync -av "$SOURCE_DIR/" "$DEST_DIR/"
audit_cron.sh
# Script de auditoría de trabajos cron
#!/bin/bash
echo "=== AUDITORÍA DE CRON $(date) ===" >> /var/log/cron_audit.log
# Listar todos los crontabs
for 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
fi
done
# Verificar integridad de archivos críticos
md5sum /etc/crontab >> /var/log/cron_audit.log
find /etc/cron.d/ -type f -exec md5sum {} \; >> /var/log/cron_audit.log
Terminal window
# En /etc/crontab, definir variables seguras
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com
# Configurar logrotate para logs de cron
cat > /etc/logrotate.d/cron << EOF
/var/log/cron {
daily
missingok
rotate 14
compress
notifempty
create 644 root root
}
EOF
CaracterísticaCronAnacron
Tipo de servicioDemonioNo es demonio
Sistemas objetivoServidores 24/7Desktops/laptops
Precisión mínima1 minuto1 día
Tareas perdidasNo se ejecutanSe ejecutan al reiniciar
ConfiguraciónCrontab individual/etc/anacrontab global
UsuariosMulti-usuarioSolo root (por defecto)
  • 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
  • El sistema no está siempre encendido
  • Las tareas pueden tolerar demora
  • Prefieres que las tareas se ejecuten eventualmente
  • Trabajas en desktops/laptops
Terminal window
# Instalar anacron
sudo apt install anacron # Ubuntu/Debian
sudo 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/anacrontab
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root
# período retraso job-identifier comando
1 5 daily-backup /usr/local/bin/backup.sh
7 10 weekly-cleanup /usr/local/bin/cleanup.sh
@monthly 15 monthly-report /usr/local/bin/report.sh
Terminal window
# Cron puede llamar a anacron para sistemas híbridos
# En /etc/crontab
0 6 * * * root anacron -s
# Esto ejecuta anacron diariamente a las 6 AM
# Anacron verificará y ejecutará tareas pendientes
#!/bin/bash
# backup.sh - Script completo de respaldo con logs y notificaciones
# Configuración
SOURCE_DIR="/home/usuario"
BACKUP_DIR="/backup"
LOG_FILE="/var/log/backup.log"
RETENTION_DAYS=30
EMAIL="admin@example.com"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="backup_$DATE.tar.gz"
# Función de logging
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
}
# Función para enviar notificaciones
notify() {
local subject="$1"
local message="$2"
echo "$message" | mail -s "$subject" $EMAIL
log "Notificación enviada: $subject"
}
# Inicio del script
log "=== INICIO DEL BACKUP ==="
log "Respaldo desde: $SOURCE_DIR"
log "Respaldo hacia: $BACKUP_DIR/$BACKUP_NAME"
# Verificar que existe el directorio fuente
if [[ ! -d "$SOURCE_DIR" ]]; then
log "ERROR: Directorio fuente no existe: $SOURCE_DIR"
notify "Backup FAILED" "Directorio fuente no existe: $SOURCE_DIR"
exit 1
fi
# Crear directorio de backup si no existe
if [[ ! -d "$BACKUP_DIR" ]]; then
mkdir -p "$BACKUP_DIR"
log "Directorio de backup creado: $BACKUP_DIR"
fi
# Verificar espacio disponible
AVAILABLE_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 1
fi
# Realizar el backup
log "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 1
fi
# Limpiar backups antiguos
log "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 backup
log "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 1
fi
log "=== FIN DEL BACKUP ==="
exit 0
#!/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 alerta
CPU_THRESHOLD=80
MEMORY_THRESHOLD=85
DISK_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 CPU
CPU_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 Memoria
MEMORY_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 Discos
df -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}%)"
fi
done
# Verificar servicios críticos
SERVICES=("ssh" "nginx" "mysql")
for service in "${SERVICES[@]}"; do
if ! systemctl is-active --quiet $service; then
alert "Servicio Inactivo" "El servicio $service no está corriendo"
fi
done
# Verificar carga del sistema
LOAD_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"
#!/bin/bash
# cleanup_logs.sh - Limpieza automática de logs
LOG_DIRS=("/var/log" "/tmp" "/var/tmp")
MAX_SIZE_MB=100
MAX_AGE_DAYS=30
REPORT_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
fi
done
# Limpiar archivos core dumps
CORE_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 final
DISK_FREED_MB=$((TOTAL_FREED))
log "Limpieza completada. Espacio liberado aproximado: ${DISK_FREED_MB}MB"
log "=== FIN DE LIMPIEZA ==="
# Enviar reporte si se liberó mucho espacio
if [[ $DISK_FREED_MB -gt 1000 ]]; then
mail -s "Limpieza de logs: ${DISK_FREED_MB}MB liberados" admin@example.com < $REPORT_FILE
fi
#!/bin/bash
# differential_backup.sh - Sistema de backup diferencial
BACKUP_BASE="/backup"
SOURCE="/home/usuario"
FULL_BACKUP_DAY=0 # Domingo
SNAPSHOT_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 rsync
rsync -av --delete --checksum "$SOURCE/" "$DEST/" >> $LOG 2>&1
# Verificar integridad comparando checksums
if 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" >> $LOG
else
echo "[$(date)] ERROR: Fallo en la verificación de integridad" >> $LOG
# Enviar alerta
mail -s "Error en sincronización" admin@example.com << EOF
La sincronización de datos falló la verificación de integridad.
Revisar inmediatamente el log: $LOG
EOF
fi
#!/bin/bash
# dynamic_resource_management.sh - Ajuste dinámico basado en carga
# Obtener carga actual del sistema
LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | tr -d ' ')
LOAD_INT=${LOAD%.*}
# Ajustar comportamiento según la carga
if [[ $LOAD_INT -lt 1 ]]; then
# Carga baja: ejecutar tareas pesadas
/usr/local/bin/heavy_maintenance.sh
/usr/local/bin/deep_scan.sh
elif [[ $LOAD_INT -lt 3 ]]; then
# Carga media: solo tareas esenciales
/usr/local/bin/essential_tasks.sh
else
# Carga alta: solo monitoreo
/usr/local/bin/quick_health_check.sh
fi
echo "[$(date)] Gestión dinámica ejecutada con carga: $LOAD"
#!/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"
fi
fi
# 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"
fi
fi
# Mantener backups mensuales (últimos 12 meses)
find "$BACKUP_DIR" -name "${PREFIX}monthly_*" -type f -mtime +365 -delete

Configuración en Crontab para Casos Avanzados

Section titled “Configuración en Crontab para Casos Avanzados”
Terminal window
# Ejemplo de crontab completo para administración de sistema
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=admin@example.com
HOME=/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.sh
  • Manual de Cron: man 8 cron
  • Manual de Crontab: man 5 crontab
  • Manual de Anacron: man 8 anacron
  • 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
Terminal window
# 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 real
tail -f /var/log/cron
# Listar todos los crontabs del sistema
for user in $(cut -f1 -d: /etc/passwd); do
echo "=== $user ==="
sudo crontab -u "$user" -l 2>/dev/null || echo "No crontab"
done
Terminal window
/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)
  1. Siempre usar rutas absolutas en scripts y comandos
  2. Configurar variables de entorno necesarias en crontab
  3. Implementar logging en todos los scripts importantes
  4. Verificar permisos de archivos y directorios
  5. Probar scripts manualmente antes de programarlos
  6. Configurar notificaciones para tareas críticas
  7. Mantener backups de configuraciones importantes
  8. Documentar el propósito de cada tarea programada
  9. Revisar regularmente logs y funcionamiento
  10. Implementar monitoreo de tareas críticas

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