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→ excluyelogs/*(todo dentro de logs/)logs/→ excluyelogs/*logs/*→ excluyelogs/*
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
.topdirignoreo--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.