Gestión de Directorios

Técnicas avanzadas para administración profesional de estructuras de directorios

Módulo 6 ⏱️ 40-45 min 📁 Directorios 🔧 Administración 📊 Intermedio

Fundamentos de la Gestión de Directorios

La gestión eficiente de directorios es fundamental para mantener sistemas organizados, seguros y fáciles de mantener. Como administrador de sistemas, dominarás técnicas avanzadas para crear, organizar, sincronizar y mantener estructuras de directorios complejas.

Creación

Estructuras complejas con permisos específicos

Sincronización

Mantener directorios actualizados y consistentes

Seguridad

Control de acceso y permisos avanzados

Monitoreo

Seguimiento de cambios y uso del espacio

Principios de Organización
  • Jerarquía lógica: Estructura que refleja la función y relaciones
  • Nomenclatura consistente: Convenciones claras para nombres
  • Separación de responsabilidades: Datos, configuración, logs separados
  • Escalabilidad: Estructura que crece ordenadamente
  • Mantenibilidad: Fácil de respaldar, limpiar y reorganizar

Creación Avanzada de Directorios

Más allá del simple mkdir, aprenderemos técnicas avanzadas para crear estructuras complejas con permisos específicos y metadatos.

Creación de Estructuras Complejas

Técnicas de creación avanzada Copiar
# Crear estructura completa de proyecto
mkdir -p proyecto/{src,docs,tests,config,logs,tmp,backups}
mkdir -p proyecto/src/{main,lib,utils}
mkdir -p proyecto/docs/{api,user,dev}
mkdir -p proyecto/tests/{unit,integration,performance}

# Verificar estructura creada
tree proyecto/
proyecto/
├── backups/
├── config/
├── docs/
│   ├── api/
│   ├── dev/
│   └── user/
├── logs/
├── src/
│   ├── lib/
│   ├── main/
│   └── utils/
├── tests/
│   ├── integration/
│   ├── performance/
│   └── unit/
└── tmp/

# Crear con permisos específicos
mkdir -m 755 public_dir          # rwxr-xr-x
mkdir -m 700 private_dir         # rwx------
mkdir -m 775 shared_dir          # rwxrwxr-x

# Crear directorios con propietario específico (como root)
sudo mkdir -p /opt/miapp/{bin,etc,var,log}
sudo chown -R usuario:grupo /opt/miapp
sudo chmod -R 755 /opt/miapp

Script para Estructuras Estandarizadas

Generador de estructuras Copiar
#!/bin/bash
# create_project_structure.sh - Generador de estructura estándar de proyectos

PROJECT_NAME="$1"
PROJECT_TYPE="${2:-web}"  # web, api, desktop, mobile

if [[ -z "$PROJECT_NAME" ]]; then
    echo "Uso: $0 nombre_proyecto [tipo]"
    echo "Tipos disponibles: web, api, desktop, mobile"
    exit 1
fi

# Validar que no existe el directorio
if [[ -d "$PROJECT_NAME" ]]; then
    echo "❌ Error: El directorio '$PROJECT_NAME' ya existe"
    exit 1
fi

echo "🏗️  Creando estructura de proyecto: $PROJECT_NAME (tipo: $PROJECT_TYPE)"

# Función para crear estructura web
create_web_structure() {
    local project="$1"
    
    # Estructura básica
    mkdir -p "$project"/{src,public,docs,tests,config,scripts,logs}
    
    # Subdirectorios específicos web
    mkdir -p "$project"/src/{components,pages,styles,assets,utils,hooks}
    mkdir -p "$project"/public/{images,css,js,fonts}
    mkdir -p "$project"/tests/{unit,e2e,integration}
    mkdir -p "$project"/docs/{design,api,deployment}
    mkdir -p "$project"/config/{development,production,testing}
    
    # Archivos básicos
    touch "$project"/README.md
    touch "$project"/.gitignore
    touch "$project"/package.json
    echo "node_modules/\n*.log\ndist/\nbuild/" > "$project"/.gitignore
}

# Función para crear estructura API
create_api_structure() {
    local project="$1"
    
    mkdir -p "$project"/{src,tests,docs,config,scripts,logs,data}
    mkdir -p "$project"/src/{controllers,models,routes,middleware,utils,services}
    mkdir -p "$project"/tests/{unit,integration,load}
    mkdir -p "$project"/docs/{api,swagger,postman}
    mkdir -p "$project"/config/{database,auth,cors}
    mkdir -p "$project"/data/{migrations,seeds,backups}
    
    touch "$project"/README.md
    touch "$project"/.env.example
    touch "$project"/server.js
}

# Función para crear estructura desktop
create_desktop_structure() {
    local project="$1"
    
    mkdir -p "$project"/{src,resources,docs,tests,build,dist}
    mkdir -p "$project"/src/{main,renderer,shared,assets}
    mkdir -p "$project"/resources/{icons,images,fonts}
    mkdir -p "$project"/tests/{unit,integration,ui}
    mkdir -p "$project"/build/{scripts,configs}
    
    touch "$project"/README.md
    touch "$project"/main.js
    touch "$project"/package.json
}

# Crear estructura según el tipo
case "$PROJECT_TYPE" in
    "web")
        create_web_structure "$PROJECT_NAME"
        ;;
    "api")
        create_api_structure "$PROJECT_NAME"
        ;;
    "desktop")
        create_desktop_structure "$PROJECT_NAME"
        ;;
    "mobile")
        mkdir -p "$PROJECT_NAME"/{src,assets,tests,docs,android,ios}
        mkdir -p "$PROJECT_NAME"/src/{components,screens,services,utils,store}
        mkdir -p "$PROJECT_NAME"/assets/{images,fonts,sounds}
        ;;
    *)
        echo "❌ Tipo de proyecto no reconocido: $PROJECT_TYPE"
        exit 1
        ;;
esac

# Establecer permisos apropiados
chmod 755 "$PROJECT_NAME"
find "$PROJECT_NAME" -type d -exec chmod 755 {} \;
find "$PROJECT_NAME" -type f -exec chmod 644 {} \;

# Crear archivo de información del proyecto
cat > "$PROJECT_NAME"/project_info.txt << EOF
Proyecto: $PROJECT_NAME
Tipo: $PROJECT_TYPE
Creado: $(date)
Usuario: $(whoami)
Hostname: $(hostname)

Estructura creada por: create_project_structure.sh
EOF

# Mostrar estructura creada
echo "✅ Estructura creada exitosamente"
echo
echo "📁 Estructura del proyecto:"
tree "$PROJECT_NAME" -L 3 2>/dev/null || find "$PROJECT_NAME" -type d | head -20

echo
echo "📋 Próximos pasos:"
echo "   cd $PROJECT_NAME"
echo "   git init"
echo "   # Comenzar desarrollo"
# Usar el script generador
$ chmod +x create_project_structure.sh

# Crear proyecto web
$ ./create_project_structure.sh mi-web-app web
🏗️  Creando estructura de proyecto: mi-web-app (tipo: web)
✅ Estructura creada exitosamente

📁 Estructura del proyecto:
mi-web-app/
├── config/
│   ├── development/
│   ├── production/
│   └── testing/
├── docs/
│   ├── api/
│   ├── deployment/
│   └── design/
├── logs/
├── public/
│   ├── css/
│   ├── fonts/
│   ├── images/
│   └── js/
├── scripts/
├── src/
│   ├── assets/
│   ├── components/
│   ├── hooks/
│   ├── pages/
│   ├── styles/
│   └── utils/
└── tests/
    ├── e2e/
    ├── integration/
    └── unit/

Copia y Sincronización

La copia y sincronización eficientes de directorios son cruciales para respaldos, despliegues y mantenimiento de sistemas distribuidos.

Copia Inteligente con rsync

Técnicas de sincronización Copiar
# Sincronización básica (local)
rsync -av /origen/ /destino/
# -a: modo archivo (preserva permisos, fechas, enlaces)
# -v: verbose (mostrar progreso)

# Sincronización con exclusiones
rsync -av --exclude='*.log' --exclude='tmp/' /proyecto/ /respaldo/

# Sincronización con progreso detallado
rsync -av --progress --stats /datos/ /backup/

# Sincronización en seco (simular sin hacer cambios)
rsync -av --dry-run /origen/ /destino/

# Sincronización remota
rsync -av -e ssh /local/ usuario@servidor:/remoto/

# Sincronización bidireccional (cuidado con conflictos)
rsync -av --delete /dir1/ /dir2/
rsync -av --delete /dir2/ /dir1/

# Sincronización con filtros complejos
rsync -av \
  --include='*.php' \
  --include='*.js' \
  --include='*/' \
  --exclude='*' \
  /proyecto/src/ /produccion/src/

Script de Sincronización Avanzada

Sincronizador automático Copiar
#!/bin/bash
# advanced_sync.sh - Sincronizador avanzado de directorios

# Configuración
SOURCE_DIR="$1"
TARGET_DIR="$2"
CONFIG_FILE="$3"
LOG_DIR="/var/log/sync"
LOG_FILE="$LOG_DIR/sync_$(date +%Y%m%d_%H%M%S).log"

# Crear directorio de logs
mkdir -p "$LOG_DIR"

# Función de logging
log_message() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
}

# Validar argumentos
if [[ $# -lt 2 ]]; then
    echo "Uso: $0   [archivo_config]"
    echo "Ejemplo: $0 /home/user/docs /backup/docs sync.conf"
    exit 1
fi

# Cargar configuración si existe
if [[ -f "$CONFIG_FILE" ]]; then
    source "$CONFIG_FILE"
    log_message "INFO" "Configuración cargada desde: $CONFIG_FILE"
else
    # Configuración por defecto
    EXCLUDE_PATTERNS=(
        "*.tmp"
        "*.log"
        "*.cache"
        ".DS_Store"
        "Thumbs.db"
        "node_modules/"
        ".git/"
        "*.pyc"
        "__pycache__/"
    )
    SYNC_OPTIONS="-av"
    BANDWIDTH_LIMIT=""
    COMPRESSION=true
    DELETE_EXCLUDED=false
    MAKE_BACKUP=true
    BACKUP_DIR="backups/"
fi

log_message "INFO" "Iniciando sincronización"
log_message "INFO" "Origen: $SOURCE_DIR"
log_message "INFO" "Destino: $TARGET_DIR"

# Verificar que el directorio origen existe
if [[ ! -d "$SOURCE_DIR" ]]; then
    log_message "ERROR" "Directorio origen no existe: $SOURCE_DIR"
    exit 1
fi

# Crear directorio destino si no existe
if [[ ! -d "$TARGET_DIR" ]]; then
    log_message "INFO" "Creando directorio destino: $TARGET_DIR"
    mkdir -p "$TARGET_DIR" || {
        log_message "ERROR" "No se pudo crear directorio destino"
        exit 1
    }
fi

# Construir comando rsync
RSYNC_CMD="rsync $SYNC_OPTIONS"

# Agregar exclusiones
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
    RSYNC_CMD+=" --exclude='$pattern'"
done

# Opciones adicionales
if [[ "$COMPRESSION" == true ]]; then
    RSYNC_CMD+=" -z"
fi

if [[ -n "$BANDWIDTH_LIMIT" ]]; then
    RSYNC_CMD+=" --bwlimit=$BANDWIDTH_LIMIT"
fi

if [[ "$DELETE_EXCLUDED" == true ]]; then
    RSYNC_CMD+=" --delete"
fi

if [[ "$MAKE_BACKUP" == true ]]; then
    RSYNC_CMD+=" --backup --backup-dir=$BACKUP_DIR"
fi

# Agregar progreso y estadísticas
RSYNC_CMD+=" --progress --stats"

# Agregar directorios
RSYNC_CMD+=" '$SOURCE_DIR/' '$TARGET_DIR/'"

log_message "INFO" "Ejecutando comando: $RSYNC_CMD"

# Ejecutar sincronización
start_time=$(date +%s)
eval "$RSYNC_CMD" 2>&1 | tee -a "$LOG_FILE"
exit_code=${PIPESTATUS[0]}
end_time=$(date +%s)
duration=$((end_time - start_time))

# Evaluar resultado
if [[ $exit_code -eq 0 ]]; then
    log_message "SUCCESS" "Sincronización completada exitosamente en ${duration}s"
else
    log_message "ERROR" "Sincronización falló con código de salida: $exit_code"
fi

# Generar estadísticas
log_message "INFO" "Generando estadísticas post-sincronización"
{
    echo "=== ESTADÍSTICAS DE SINCRONIZACIÓN ==="
    echo "Fecha: $(date)"
    echo "Origen: $SOURCE_DIR"
    echo "Destino: $TARGET_DIR"
    echo "Duración: ${duration}s"
    echo "Código de salida: $exit_code"
    echo
    echo "Espacio utilizado:"
    du -sh "$SOURCE_DIR" 2>/dev/null | awk '{print "  Origen: " $1}'
    du -sh "$TARGET_DIR" 2>/dev/null | awk '{print "  Destino: " $1}'
    echo
    echo "Archivos más recientes en destino:"
    find "$TARGET_DIR" -type f -newer "$LOG_FILE" 2>/dev/null | head -10 || echo "  Ninguno"
} >> "$LOG_FILE"

# Cleanup de logs antiguos (mantener últimos 30 días)
find "$LOG_DIR" -name "sync_*.log" -type f -mtime +30 -delete 2>/dev/null

log_message "INFO" "Log guardado en: $LOG_FILE"

exit $exit_code

Archivo de Configuración

# sync.conf - Archivo de configuración para advanced_sync.sh

# Patrones a excluir
EXCLUDE_PATTERNS=(
    "*.tmp"
    "*.log"
    "*.pid"
    "*.swp"
    "*.cache"
    ".DS_Store"
    "Thumbs.db"
    "node_modules/"
    ".git/"
    "*.pyc"
    "__pycache__/"
    "venv/"
    ".env"
    "database.sqlite"
)

# Opciones de rsync
SYNC_OPTIONS="-av --partial --timeout=300"

# Límite de ancho de banda (KB/s) - vacío para sin límite
BANDWIDTH_LIMIT="1000"

# Usar compresión (true/false)
COMPRESSION=true

# Eliminar archivos del destino que no existen en origen
DELETE_EXCLUDED=true

# Crear respaldos de archivos modificados
MAKE_BACKUP=true
BACKUP_DIR="backups/$(date +%Y%m%d_%H%M%S)/"

# Usar el script
$ chmod +x advanced_sync.sh
$ ./advanced_sync.sh /home/user/proyecto /backup/proyecto sync.conf

Análisis de Uso del Espacio

El monitoreo del uso del espacio en directorios es esencial para mantener sistemas eficientes y prevenir problemas de almacenamiento.

Herramientas de Análisis

# Uso básico con du
$ du -h /var/log | sort -hr | head -10
2.1G    /var/log
1.8G    /var/log/apache2
256M    /var/log/syslog
89M     /var/log/auth.log
45M     /var/log/kern.log

# Análisis por profundidad
$ du -h --max-depth=2 /opt | sort -hr
1.5G    /opt
890M    /opt/google
512M    /opt/microsoft
256M    /opt/local/bin
128M    /opt/local/lib

# Solo directorios (sin archivos individuales)
$ du -sh */ | sort -hr
3.2G    Videos/
1.8G    Documents/
567M    Pictures/
234M    Downloads/

# Encontrar archivos grandes
$ find /var -type f -size +100M -exec du -h {} + | sort -hr
2.1G    /var/log/huge.log
567M    /var/lib/mysql/database.sql
234M    /var/cache/large_file.cache

Analizador Avanzado de Espacio

Analizador de uso de disco Copiar
#!/bin/bash
# disk_analyzer.sh - Analizador avanzado de uso de disco

TARGET_DIR="${1:-.}"
REPORT_FILE="disk_analysis_$(date +%Y%m%d_%H%M%S).html"
THRESHOLD_MB=100

# Función para convertir bytes a formato legible
human_readable() {
    local bytes=$1
    local units=("B" "KB" "MB" "GB" "TB")
    local unit=0
    
    while [[ $bytes -gt 1024 && $unit -lt 4 ]]; do
        bytes=$((bytes / 1024))
        ((unit++))
    done
    
    echo "${bytes}${units[$unit]}"
}

# Generar reporte HTML
cat > "$REPORT_FILE" << 'EOF'




    Análisis de Uso de Disco
    


EOF

# Header del reporte
cat >> "$REPORT_FILE" << EOF
    

📊 Análisis de Uso de Disco

Directorio analizado: $(realpath "$TARGET_DIR")

Fecha: $(date)

Host: $(hostname)

EOF echo "🔍 Analizando directorio: $TARGET_DIR" echo "📊 Generando reporte: $REPORT_FILE" # 1. RESUMEN GENERAL echo "
" >> "$REPORT_FILE" echo "

📋 Resumen General

" >> "$REPORT_FILE" TOTAL_SIZE=$(du -sb "$TARGET_DIR" 2>/dev/null | cut -f1) TOTAL_FILES=$(find "$TARGET_DIR" -type f 2>/dev/null | wc -l) TOTAL_DIRS=$(find "$TARGET_DIR" -type d 2>/dev/null | wc -l) cat >> "$REPORT_FILE" << EOF
MétricaValor
Tamaño Total$(human_readable $TOTAL_SIZE)
Archivos$TOTAL_FILES
Directorios$TOTAL_DIRS
Última modificación$(stat -c %y "$TARGET_DIR" 2>/dev/null | cut -d'.' -f1)
EOF echo "
" >> "$REPORT_FILE" # 2. TOP DIRECTORIOS echo "
" >> "$REPORT_FILE" echo "

📁 Top 10 Directorios por Tamaño

" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" du -sb "$TARGET_DIR"/* 2>/dev/null | sort -nr | head -10 | while read size path; do percentage=$(( (size * 100) / TOTAL_SIZE )) bar_width=$(( percentage > 100 ? 100 : percentage )) # Determinar clase de color if [[ $percentage -gt 50 ]]; then bar_class="progress-critical" elif [[ $percentage -gt 25 ]]; then bar_class="progress-warning" else bar_class="" fi cat >> "$REPORT_FILE" << EOF EOF done echo "
DirectorioTamaño% del TotalBarra
$(basename "$path") $(human_readable $size) ${percentage}%
" >> "$REPORT_FILE" # 3. ARCHIVOS GRANDES echo "
" >> "$REPORT_FILE" echo "

📄 Archivos Más Grandes

" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" find "$TARGET_DIR" -type f -size +${THRESHOLD_MB}M 2>/dev/null | \ xargs ls -la 2>/dev/null | sort -k5 -nr | head -20 | \ while read -r permissions links owner group size month day time_or_year filepath; do filename=$(basename "$filepath") dirpath=$(dirname "$filepath" | sed "s|^$TARGET_DIR/||") cat >> "$REPORT_FILE" << EOF EOF done echo "
ArchivoTamañoDirectorioÚltima Modificación
$filename $(human_readable $size) $dirpath $month $day $time_or_year
" >> "$REPORT_FILE" # 4. ANÁLISIS POR TIPO DE ARCHIVO echo "
" >> "$REPORT_FILE" echo "

🎯 Análisis por Tipo de Archivo

" >> "$REPORT_FILE" # Crear archivo temporal para estadísticas por extensión TEMP_FILE=$(mktemp) find "$TARGET_DIR" -type f 2>/dev/null | while read file; do extension="${file##*.}" if [[ "$extension" == "$(basename "$file")" ]]; then extension="sin_extension" fi size=$(stat -c%s "$file" 2>/dev/null || echo 0) echo "$extension $size" done > "$TEMP_FILE" echo "" >> "$REPORT_FILE" echo "" >> "$REPORT_FILE" awk '{ext[$1]++; size[$1]+=$2} END { for(e in ext) print ext[e], size[e], e }' "$TEMP_FILE" | sort -nr | head -15 | while read count total_size ext; do percentage=$(( (total_size * 100) / TOTAL_SIZE )) cat >> "$REPORT_FILE" << EOF EOF done echo "
ExtensiónArchivosTamaño Total% del Total
.$ext $count $(human_readable $total_size) ${percentage}%
" >> "$REPORT_FILE" # 5. ARCHIVOS ANTIGUOS (no modificados en 6 meses) echo "
" >> "$REPORT_FILE" echo "

🕰️ Archivos Antiguos (sin modificar >6 meses)

" >> "$REPORT_FILE" OLD_FILES=$(find "$TARGET_DIR" -type f -mtime +180 2>/dev/null | wc -l) OLD_SIZE=$(find "$TARGET_DIR" -type f -mtime +180 2>/dev/null -exec stat -c%s {} + 2>/dev/null | awk '{sum+=$1} END {print sum+0}') if [[ $OLD_FILES -gt 0 ]]; then cat >> "$REPORT_FILE" << EOF

⚠️ Archivos antiguos detectados:

  • Cantidad: $OLD_FILES archivos
  • Espacio ocupado: $(human_readable $OLD_SIZE)
  • % del total: $(( (OLD_SIZE * 100) / TOTAL_SIZE ))%
EOF else echo "

✅ No se encontraron archivos antiguos

" >> "$REPORT_FILE" fi echo "
" >> "$REPORT_FILE" # Cerrar HTML echo "" >> "$REPORT_FILE" # Cleanup rm -f "$TEMP_FILE" 2>/dev/null echo "✅ Análisis completado" echo "📄 Reporte generado: $REPORT_FILE" echo "🌐 Abrir con: firefox $REPORT_FILE" # Mostrar resumen en terminal echo echo "📊 RESUMEN RÁPIDO:" echo " Tamaño total: $(human_readable $TOTAL_SIZE)" echo " Archivos: $TOTAL_FILES" echo " Directorios: $TOTAL_DIRS" if [[ $OLD_FILES -gt 0 ]]; then echo " ⚠️ Archivos antiguos: $OLD_FILES ($(human_readable $OLD_SIZE))" fi

Permisos y Seguridad Avanzada

La gestión de permisos en directorios va más allá de rwx básico. Exploraremos ACLs, atributos extendidos y técnicas avanzadas de seguridad.

Permisos Especiales

Bit Especial Símbolo Octal Función en Directorio Ejemplo
Sticky Bit t 1000 Solo el propietario puede eliminar archivos /tmp (drwxrwxrwt)
SGID s (grupo) 2000 Nuevos archivos heredan el grupo del directorio Directorios compartidos
SUID s (usuario) 4000 Raramente usado en directorios N/A
Configuración de permisos avanzados Copiar
# Crear directorio compartido con SGID
mkdir /shared/project
chmod 2775 /shared/project  # rwxrwsr-x
chgrp developers /shared/project

# Verificar que funciona
ls -ld /shared/project
drwxrwsr-x 2 root developers 4096 oct 15 10:30 /shared/project

# Todos los archivos creados heredarán el grupo 'developers'
touch /shared/project/test.txt
ls -l /shared/project/test.txt
-rw-r--r-- 1 usuario developers 0 oct 15 10:31 test.txt

# Configurar directorio temporal con sticky bit
mkdir /tmp/shared
chmod 1777 /tmp/shared  # rwxrwxrwt
ls -ld /tmp/shared
drwxrwxrwt 2 root root 4096 oct 15 10:32 /tmp/shared

# ACLs (Access Control Lists) - más granular
# Instalar herramientas ACL si no están disponibles
# sudo apt-get install acl

# Dar permisos específicos a usuario
setfacl -m u:alice:rx /proyecto/datos
setfacl -m g:developers:rwx /proyecto/src

# Ver ACLs
getfacl /proyecto/datos
# file: proyecto/datos
# owner: root
# group: root
# user::rwx
# user:alice:r-x
# group::r-x
# mask::r-x
# other::---

# Establecer ACLs por defecto (para nuevos archivos)
setfacl -d -m g:developers:rwx /proyecto/src

# Remover ACLs
setfacl -x u:alice /proyecto/datos

Auditor de Seguridad de Directorios

Auditor de seguridad Copiar
#!/bin/bash
# security_audit.sh - Auditor de seguridad para directorios

AUDIT_DIR="${1:-.}"
REPORT_FILE="security_audit_$(date +%Y%m%d_%H%M%S).txt"

echo "🔒 AUDITORÍA DE SEGURIDAD DE DIRECTORIOS" > "$REPORT_FILE"
echo "===========================================" >> "$REPORT_FILE"
echo "Directorio: $(realpath "$AUDIT_DIR")" >> "$REPORT_FILE"
echo "Fecha: $(date)" >> "$REPORT_FILE"
echo "Usuario: $(whoami)" >> "$REPORT_FILE"
echo >> "$REPORT_FILE"

# Función para logging
audit_log() {
    echo "$1" | tee -a "$REPORT_FILE"
}

# 1. PERMISOS PELIGROSOS
audit_log "🚨 1. VERIFICACIÓN DE PERMISOS PELIGROSOS"
audit_log "============================================"

# Directorios escribibles por todos
WORLD_WRITABLE=$(find "$AUDIT_DIR" -type d -perm -002 2>/dev/null)
if [[ -n "$WORLD_WRITABLE" ]]; then
    audit_log "⚠️ ADVERTENCIA: Directorios escribibles por todos:"
    echo "$WORLD_WRITABLE" | while read dir; do
        perms=$(ls -ld "$dir" | cut -d' ' -f1)
        audit_log "   $perms $dir"
    done
else
    audit_log "✅ No se encontraron directorios escribibles por todos"
fi

audit_log ""

# Archivos SUID/SGID
SUID_FILES=$(find "$AUDIT_DIR" -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null)
if [[ -n "$SUID_FILES" ]]; then
    audit_log "⚠️ ADVERTENCIA: Archivos con SUID/SGID:"
    echo "$SUID_FILES" | while read file; do
        perms=$(ls -l "$file" | cut -d' ' -f1)
        audit_log "   $perms $file"
    done
else
    audit_log "✅ No se encontraron archivos SUID/SGID"
fi

audit_log ""

# 2. PROPIETARIOS SOSPECHOSOS
audit_log "👤 2. VERIFICACIÓN DE PROPIETARIOS"
audit_log "=================================="

# Archivos sin propietario (UID no existe)
NO_OWNER=$(find "$AUDIT_DIR" -nouser 2>/dev/null)
if [[ -n "$NO_OWNER" ]]; then
    audit_log "⚠️ ADVERTENCIA: Archivos sin propietario válido:"
    echo "$NO_OWNER" | head -10 | while read file; do
        stat_info=$(stat -c "%n %u:%g %a" "$file" 2>/dev/null)
        audit_log "   $stat_info"
    done
    total_no_owner=$(echo "$NO_OWNER" | wc -l)
    if [[ $total_no_owner -gt 10 ]]; then
        audit_log "   ... y $((total_no_owner - 10)) más"
    fi
else
    audit_log "✅ Todos los archivos tienen propietario válido"
fi

audit_log ""

# Archivos sin grupo válido
NO_GROUP=$(find "$AUDIT_DIR" -nogroup 2>/dev/null)
if [[ -n "$NO_GROUP" ]]; then
    audit_log "⚠️ ADVERTENCIA: Archivos sin grupo válido:"
    echo "$NO_GROUP" | head -5 | while read file; do
        audit_log "   $file"
    done
else
    audit_log "✅ Todos los archivos tienen grupo válido"
fi

audit_log ""

# 3. ARCHIVOS EJECUTABLES SOSPECHOSOS
audit_log "⚡ 3. VERIFICACIÓN DE EJECUTABLES"
audit_log "==============================="

# Scripts sin extensión ejecutables
SUSPICIOUS_SCRIPTS=$(find "$AUDIT_DIR" -type f -executable \! -name "*.sh" \! -name "*.py" \! -name "*.pl" \! -name "*.rb" 2>/dev/null | grep -v "/bin/" | head -10)
if [[ -n "$SUSPICIOUS_SCRIPTS" ]]; then
    audit_log "⚠️ ADVERTENCIA: Scripts ejecutables sin extensión:"
    echo "$SUSPICIOUS_SCRIPTS" | while read script; do
        file_type=$(file "$script" | cut -d':' -f2)
        audit_log "   $script -$file_type"
    done
else
    audit_log "✅ No se encontraron scripts sospechosos"
fi

audit_log ""

# 4. ARCHIVOS TEMPORALES Y BASURA
audit_log "🗑️ 4. VERIFICACIÓN DE ARCHIVOS TEMPORALES"
audit_log "========================================"

TEMP_PATTERNS=("*.tmp" "*.temp" "*~" "*.bak" "*.swp" "core")
for pattern in "${TEMP_PATTERNS[@]}"; do
    temp_files=$(find "$AUDIT_DIR" -name "$pattern" -type f 2>/dev/null | wc -l)
    if [[ $temp_files -gt 0 ]]; then
        total_size=$(find "$AUDIT_DIR" -name "$pattern" -type f -exec stat -c%s {} + 2>/dev/null | awk '{sum+=$1} END {print sum+0}')
        audit_log "   $pattern: $temp_files archivos ($(( total_size / 1024 ))KB)"
    fi
done

audit_log ""

# 5. ENLACES SIMBÓLICOS
audit_log "🔗 5. VERIFICACIÓN DE ENLACES SIMBÓLICOS"
audit_log "======================================="

# Enlaces rotos
BROKEN_LINKS=$(find "$AUDIT_DIR" -type l \! -exec test -e {} \; -print 2>/dev/null)
if [[ -n "$BROKEN_LINKS" ]]; then
    audit_log "⚠️ ADVERTENCIA: Enlaces simbólicos rotos:"
    echo "$BROKEN_LINKS" | head -10 | while read link; do
        target=$(readlink "$link")
        audit_log "   $link -> $target (no existe)"
    done
else
    audit_log "✅ Todos los enlaces simbólicos son válidos"
fi

audit_log ""

# Enlaces que apuntan fuera del directorio auditado
EXTERNAL_LINKS=$(find "$AUDIT_DIR" -type l -exec readlink {} \; | grep "^/" | grep -v "^$(realpath "$AUDIT_DIR")" 2>/dev/null | wc -l)
if [[ $EXTERNAL_LINKS -gt 0 ]]; then
    audit_log "ℹ️ INFO: $EXTERNAL_LINKS enlaces apuntan fuera del directorio auditado"
else
    audit_log "✅ Todos los enlaces son internos"
fi

audit_log ""

# 6. RESUMEN FINAL
audit_log "📊 6. RESUMEN DE AUDITORÍA"
audit_log "========================"

total_files=$(find "$AUDIT_DIR" -type f 2>/dev/null | wc -l)
total_dirs=$(find "$AUDIT_DIR" -type d 2>/dev/null | wc -l)
total_links=$(find "$AUDIT_DIR" -type l 2>/dev/null | wc -l)

audit_log "Total de archivos: $total_files"
audit_log "Total de directorios: $total_dirs"
audit_log "Total de enlaces: $total_links"

# Calcular puntuación de seguridad (simple)
security_score=100
[[ -n "$WORLD_WRITABLE" ]] && security_score=$((security_score - 20))
[[ -n "$SUID_FILES" ]] && security_score=$((security_score - 15))
[[ -n "$NO_OWNER" ]] && security_score=$((security_score - 10))
[[ -n "$NO_GROUP" ]] && security_score=$((security_score - 5))
[[ -n "$BROKEN_LINKS" ]] && security_score=$((security_score - 5))

audit_log ""
if [[ $security_score -ge 80 ]]; then
    audit_log "🟢 PUNTUACIÓN DE SEGURIDAD: $security_score/100 (BUENA)"
elif [[ $security_score -ge 60 ]]; then
    audit_log "🟡 PUNTUACIÓN DE SEGURIDAD: $security_score/100 (MEDIA)"
else
    audit_log "🔴 PUNTUACIÓN DE SEGURIDAD: $security_score/100 (BAJA)"
fi

audit_log ""
audit_log "📄 Reporte completo guardado en: $REPORT_FILE"

# Mostrar resumen en pantalla
echo
echo "🔒 AUDITORÍA COMPLETADA"
echo "Puntuación de seguridad: $security_score/100"
echo "Reporte guardado en: $REPORT_FILE"

Ejercicio Práctico Final

Proyecto: Sistema Integral de Gestión de Directorios

Crea un sistema completo que integre todas las técnicas aprendidas:

Gestor integral de directorios Copiar
#!/bin/bash
# directory_manager.sh - Sistema integral de gestión de directorios

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SCRIPT_DIR/dir_manager.conf"
LOG_FILE="$SCRIPT_DIR/logs/directory_manager.log"

# Crear directorio de logs
mkdir -p "$SCRIPT_DIR/logs"

# Configuración por defecto
DEFAULT_BACKUP_DIR="/backup"
DEFAULT_SYNC_OPTIONS="-av --progress"
DEFAULT_SECURITY_LEVEL="medium"

# Cargar configuración
if [[ -f "$CONFIG_FILE" ]]; then
    source "$CONFIG_FILE"
fi

# Función de ayuda
show_help() {
    cat << EOF
Directory Manager - Sistema integral de gestión de directorios

Uso: $0 [comando] [opciones]

Comandos disponibles:
    create       - Crear estructura de proyecto
    sync      - Sincronizar directorios
    analyze        - Análizar uso del espacio
    audit          - Auditoría de seguridad
    backup         - Crear respaldo
    monitor        - Monitorear cambios
    cleanup        - Limpiar archivos temporales
    status                     - Estado del sistema

Tipos de proyecto para 'create':
    web, api, desktop, mobile, data, docs

Ejemplos:
    $0 create mi-proyecto web
    $0 sync /home/user/docs /backup/docs
    $0 analyze /var/log
    $0 audit /opt/aplicacion
    
Para configuración avanzada, edita: $CONFIG_FILE
EOF
}

# Función de logging
log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# Comando: create
cmd_create() {
    local name="$1"
    local type="${2:-web}"
    
    if [[ -z "$name" ]]; then
        echo "Error: Especifica el nombre del proyecto"
        exit 1
    fi
    
    log_message "Creando proyecto: $name (tipo: $type)"
    
    # Usar el script create_project_structure.sh si existe
    if [[ -x "$SCRIPT_DIR/create_project_structure.sh" ]]; then
        "$SCRIPT_DIR/create_project_structure.sh" "$name" "$type"
    else
        # Implementación básica
        mkdir -p "$name"/{src,docs,tests,config}
        chmod 755 "$name"
        log_message "Estructura básica creada para $name"
    fi
}

# Comando: sync
cmd_sync() {
    local source="$1"
    local target="$2"
    
    if [[ -z "$source" || -z "$target" ]]; then
        echo "Error: Especifica directorio origen y destino"
        exit 1
    fi
    
    log_message "Sincronizando $source -> $target"
    
    # Usar advanced_sync.sh si existe
    if [[ -x "$SCRIPT_DIR/advanced_sync.sh" ]]; then
        "$SCRIPT_DIR/advanced_sync.sh" "$source" "$target"
    else
        # Sincronización básica
        rsync -av --progress "$source/" "$target/"
    fi
}

# Comando: analyze
cmd_analyze() {
    local directory="${1:-.}"
    
    log_message "Analizando uso del espacio: $directory"
    
    if [[ -x "$SCRIPT_DIR/disk_analyzer.sh" ]]; then
        "$SCRIPT_DIR/disk_analyzer.sh" "$directory"
    else
        echo "📊 Análisis básico de $directory:"
        du -sh "$directory"/* 2>/dev/null | sort -hr | head -10
    fi
}

# Comando: audit
cmd_audit() {
    local directory="${1:-.}"
    
    log_message "Auditando seguridad: $directory"
    
    if [[ -x "$SCRIPT_DIR/security_audit.sh" ]]; then
        "$SCRIPT_DIR/security_audit.sh" "$directory"
    else
        echo "🔒 Auditoría básica de seguridad:"
        find "$directory" -type f -perm -002 2>/dev/null | head -5
    fi
}

# Comando: backup
cmd_backup() {
    local directory="$1"
    local backup_name="backup_$(basename "$directory")_$(date +%Y%m%d_%H%M%S)"
    local backup_path="$DEFAULT_BACKUP_DIR/$backup_name"
    
    if [[ -z "$directory" ]]; then
        echo "Error: Especifica el directorio a respaldar"
        exit 1
    fi
    
    log_message "Creando respaldo: $directory -> $backup_path"
    
    mkdir -p "$DEFAULT_BACKUP_DIR"
    tar -czf "$backup_path.tar.gz" -C "$(dirname "$directory")" "$(basename "$directory")" 2>/dev/null
    
    if [[ $? -eq 0 ]]; then
        log_message "Respaldo creado exitosamente: $backup_path.tar.gz"
        echo "✅ Respaldo guardado en: $backup_path.tar.gz"
    else
        log_message "Error al crear respaldo"
        echo "❌ Error al crear respaldo"
        exit 1
    fi
}

# Comando: monitor
cmd_monitor() {
    local directory="${1:-.}"
    
    log_message "Iniciando monitoreo de: $directory"
    
    if command -v inotifywait >/dev/null 2>&1; then
        echo "👁️ Monitoreando cambios en $directory (Ctrl+C para detener)"
        inotifywait -m -r -e create,delete,modify,move "$directory" 2>/dev/null | \
        while read path event file; do
            log_message "EVENTO: $event en $path$file"
            echo "[$(date '+%H:%M:%S')] $event: $path$file"
        done
    else
        echo "⚠️ inotify-tools no está instalado. Monitoreando básico..."
        echo "Para monitoreo avanzado instala: sudo apt-get install inotify-tools"
        
        # Monitoreo básico con watch
        watch -n 5 "find '$directory' -newer '$LOG_FILE' 2>/dev/null | head -10"
    fi
}

# Comando: cleanup
cmd_cleanup() {
    local directory="${1:-.}"
    local temp_patterns=("*.tmp" "*.temp" "*~" "*.bak" ".DS_Store" "Thumbs.db")
    
    log_message "Limpiando archivos temporales en: $directory"
    
    echo "🧹 Limpiando archivos temporales..."
    
    local total_removed=0
    local total_size=0
    
    for pattern in "${temp_patterns[@]}"; do
        files_found=$(find "$directory" -name "$pattern" -type f 2>/dev/null)
        if [[ -n "$files_found" ]]; then
            count=$(echo "$files_found" | wc -l)
            size=$(echo "$files_found" | xargs stat -c%s 2>/dev/null | awk '{sum+=$1} END {print sum+0}')
            
            echo "$files_found" | xargs rm -f 2>/dev/null
            
            echo "  Removidos: $count archivos $pattern ($(( size / 1024 ))KB)"
            total_removed=$((total_removed + count))
            total_size=$((total_size + size))
        fi
    done
    
    if [[ $total_removed -gt 0 ]]; then
        log_message "Limpieza completada: $total_removed archivos, $(( total_size / 1024 ))KB liberados"
        echo "✅ Limpieza completada: $total_removed archivos removidos"
    else
        echo "✨ No se encontraron archivos temporales"
    fi
}

# Comando: status
cmd_status() {
    echo "📊 ESTADO DEL SISTEMA DE GESTIÓN DE DIRECTORIOS"
    echo "=============================================="
    echo
    echo "📁 Configuración:"
    echo "  Directorio de trabajo: $SCRIPT_DIR"
    echo "  Archivo de configuración: $CONFIG_FILE"
    echo "  Log: $LOG_FILE"
    echo "  Directorio de respaldos: $DEFAULT_BACKUP_DIR"
    echo
    echo "🔧 Herramientas disponibles:"
    
    tools=("rsync" "tree" "inotifywait" "setfacl" "getfacl")
    for tool in "${tools[@]}"; do
        if command -v "$tool" >/dev/null 2>&1; then
            echo "  ✅ $tool"
        else
            echo "  ❌ $tool (no instalado)"
        fi
    done
    
    echo
    echo "📊 Estadísticas de logs:"
    if [[ -f "$LOG_FILE" ]]; then
        line_count=$(wc -l < "$LOG_FILE")
        last_entry=$(tail -1 "$LOG_FILE" 2>/dev/null | cut -d']' -f1 | tr -d '[')
        echo "  Líneas en log: $line_count"
        echo "  Última entrada: $last_entry"
    else
        echo "  No hay archivo de log"
    fi
    
    echo
    echo "💾 Espacio en disco:"
    df -h . | tail -1 | awk '{printf "  Disponible: %s de %s (%s usado)\n", $4, $2, $5}'
}

# Función principal
main() {
    case "$1" in
        "create")
            cmd_create "$2" "$3"
            ;;
        "sync")
            cmd_sync "$2" "$3"
            ;;
        "analyze")
            cmd_analyze "$2"
            ;;
        "audit")
            cmd_audit "$2"
            ;;
        "backup")
            cmd_backup "$2"
            ;;
        "monitor")
            cmd_monitor "$2"
            ;;
        "cleanup")
            cmd_cleanup "$2"
            ;;
        "status")
            cmd_status
            ;;
        "help"|"--help"|"-h"|"")
            show_help
            ;;
        *)
            echo "Comando no reconocido: $1"
            echo "Usa '$0 help' para ver comandos disponibles"
            exit 1
            ;;
    esac
}

# Ejecutar función principal
main "$@"

Para usar el sistema:

# Hacer executable
chmod +x directory_manager.sh

# Ver ayuda
./directory_manager.sh help

# Crear proyecto
./directory_manager.sh create mi-web-app web

# Sincronizar directorios
./directory_manager.sh sync /home/user/docs /backup/docs

# Analizar uso del espacio
./directory_manager.sh analyze /var/log

# Auditoría de seguridad
./directory_manager.sh audit /opt/aplicacion

# Crear respaldo
./directory_manager.sh backup /home/user/proyecto

# Ver estado del sistema
./directory_manager.sh status