Files
topdir/README.md
2025-11-01 17:35:58 +01:00

7.6 KiB

topdir.sh

Script en bash que compara recursivamente un directorio y genera informes de archivos nuevos, modificados y eliminados desde la última ejecución.

Características

  • 🔍 Detección de cambios: Identifica archivos nuevos, modificados y eliminados
  • 🔐 Múltiples algoritmos de hash: SHA256 (default), SHA1, MD5
  • 📊 Formatos de salida: Text (humano), JSON (programático), CSV (hoja de cálculo)
  • 🚫 Sistema de exclusiones: Excluye archivos/directorios por patrón o archivo .topdirignore
  • 💾 Snapshot personalizable: Ubicación configurable del archivo de estado
  • Portable: Bash estándar con utilidades comunes (find, sed, awk)

Instalación

chmod +x topdir.sh
# Opcionalmente, mover a un directorio en tu PATH
sudo cp topdir.sh /usr/local/bin/topdir

Uso básico

# Monitorear directorio actual
./topdir.sh

# Monitorear directorio específico
./topdir.sh /path/to/directory

# Ver ayuda completa
./topdir.sh --help

Primera ejecución

La primera vez que ejecutas el script en un directorio, crea un archivo .topdir_snapshot con el estado inicial:

$ ./topdir.sh /data
Snapshot creado en './.topdir_snapshot' (no había ejecución previa).

Ejecuciones posteriores

Las siguientes ejecuciones comparan contra el snapshot y muestran cambios:

$ ./topdir.sh /data
Informe de comparación para: /data

Nuevos archivos (2):
  ./report.pdf
  ./images/photo.jpg

Archivos modificados (1):
  ./config.txt

Archivos eliminados desde último snapshot (1):
  ./temp.log

Opciones avanzadas

Algoritmos de hash

Elige entre SHA256 (default), SHA1 o MD5:

# Usar MD5 (más rápido para archivos grandes)
./topdir.sh --hash md5 /data

# Usar SHA1
./topdir.sh --hash sha1 /data

Formatos de salida

Formato Text (default)

Salida legible para humanos:

./topdir.sh /data

Formato JSON

Para procesamiento programático:

./topdir.sh --format json /data

Salida:

{
  "status": "ok",
  "directory": "/data",
  "hash": "sha256",
  "new": ["./file1.txt", "./file2.txt"],
  "modified": ["./config.json"],
  "deleted": ["./old.log"]
}

Formato CSV

Para análisis en hojas de cálculo:

./topdir.sh --format csv /data

Salida:

status,path
new,"./file1.txt"
new,"./file2.txt"
modified,"./config.json"
deleted,"./old.log"

Exclusiones de archivos

Opción --exclude

Excluye patrones específicos (puede repetirse):

# Excluir extensiones
./topdir.sh --exclude "*.log" --exclude "*.tmp" /data

# Excluir carpetas completas (recursivamente)
./topdir.sh --exclude "node_modules" --exclude "logs" /project
# O con formato explícito:
./topdir.sh --exclude "node_modules/*" --exclude ".git/*" /project

# Excluir subdirectorios específicos
./topdir.sh --exclude "src/test/*" --exclude "docs/drafts" /project

Tip: Si el patrón es solo un nombre de carpeta (sin * ni / al final), el script verifica si existe como directorio y automáticamente añade /* para exclusión recursiva.

Archivo .topdirignore

Crea un archivo .topdirignore en el directorio monitoreado con patrones (similar a .gitignore):

# .topdirignore

# Extensiones - excluye archivos con estas extensiones en cualquier ubicación
*.log
*.tmp
*.pyc

# Carpetas - excluye recursivamente (automático)
node_modules
.git
__pycache__
cache
logs
build

# También puedes usar estos formatos (equivalentes):
node_modules/
node_modules/*

# Patrones específicos
temp/*
dist/*.js

Importante: Para excluir carpetas, simplemente pon el nombre de la carpeta. El script automáticamente lo convierte a exclusión recursiva (añade /*). Los siguientes formatos son equivalentes:

  • logs → excluye logs/* (todo dentro de logs/)
  • logs/ → excluye logs/*
  • logs/* → excluye logs/*

Luego ejecuta normalmente:

./topdir.sh /project
# Lee automáticamente .topdirignore

Archivo de exclusión personalizado

./topdir.sh --ignore-file /path/to/custom.ignore /data

Snapshot personalizado

Por defecto, el snapshot se guarda como .topdir_snapshot dentro del directorio monitoreado. Puedes especificar una ubicación diferente:

# Snapshot en /tmp
./topdir.sh --snapshot-file /tmp/data.snapshot /data

# Snapshot en directorio home
./topdir.sh --snapshot-file ~/snapshots/project.snap /project

Útil para:

  • Monitorear directorios de solo lectura
  • Mantener múltiples snapshots del mismo directorio
  • Guardar snapshots en almacenamiento centralizado

Ejemplos completos

Monitoreo de proyecto de desarrollo

# Primera ejecución - crear snapshot con MD5 y excluir archivos de build
./topdir.sh --hash md5 \
  --exclude "node_modules/*" \
  --exclude "dist/*" \
  --exclude "*.log" \
  /home/user/myproject

# Después de trabajar, verificar cambios en JSON
./topdir.sh --hash md5 \
  --format json \
  --exclude "node_modules/*" \
  --exclude "dist/*" \
  --exclude "*.log" \
  /home/user/myproject | jq .

Monitoreo de directorio de datos

# Snapshot en ubicación centralizada, salida CSV
./topdir.sh --snapshot-file /var/snapshots/data.snap \
  --format csv \
  --exclude "*.tmp" \
  /data > changes.csv

Integración con cron

# Agregar a crontab para chequeo diario
# 0 3 * * * /usr/local/bin/topdir --format json --snapshot-file /var/snapshots/backup.snap /backup > /var/log/topdir.json 2>&1

Comparar con snapshot anterior sin actualizar

Si quieres ver cambios sin actualizar el snapshot:

# Hacer backup del snapshot
cp /data/.topdir_snapshot /tmp/snapshot.bak

# Ejecutar topdir (actualiza el snapshot)
./topdir.sh /data

# Restaurar snapshot original
mv /tmp/snapshot.bak /data/.topdir_snapshot

Notas técnicas

Rendimiento

  • SHA256: Más seguro, recomendado para verificación de integridad (default)
  • SHA1: Balance entre velocidad y seguridad
  • MD5: Más rápido, adecuado para detección de cambios en archivos grandes (no para seguridad)

Limitaciones

  • Los archivos con nombres que contienen saltos de línea pueden no procesarse correctamente
  • El script no sigue enlaces simbólicos (por diseño)
  • Requiere bash >= 3.2 y utilidades estándar (find, sed, awk, sha256sum/sha1sum/md5sum)

Archivos excluidos automáticamente

El script siempre excluye:

  • .topdir_snapshot (archivo de estado)
  • .topdirignore (archivo de configuración de exclusiones)

Formato del snapshot

El snapshot es un archivo de texto con formato:

<path><TAB><hash>

Ejemplo:

./file1.txt	e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
./file2.txt	d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35

Solución de problemas

"Command not found: sha256sum"

En macOS, instala coreutils:

brew install coreutils

O usa SHA1/MD5 que vienen preinstalados:

./topdir.sh --hash sha1 /data

"Snapshot file not found" en ejecuciones posteriores

Asegúrate de usar la misma opción --snapshot-file en todas las ejecuciones:

# Primera ejecución
./topdir.sh --snapshot-file /tmp/my.snap /data

# Ejecuciones posteriores - debe usar el mismo snapshot
./topdir.sh --snapshot-file /tmp/my.snap /data

Archivos no se detectan como modificados

  • Verifica que no estén excluidos por .topdirignore o --exclude
  • Confirma que el contenido cambió (el script usa hash, no mtime)
  • Verifica que usas el mismo algoritmo de hash (--hash)

Licencia

Dominio público / MIT - Usa como quieras.

Autor

Creado para monitoreo sencillo de cambios en directorios sin dependencias pesadas.