71
topdir.sh
71
topdir.sh
@@ -117,6 +117,13 @@ cleanup() {
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Mostrar configuración si el formato es text
|
||||
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
|
||||
echo "[topdir] Iniciando análisis..."
|
||||
echo "[topdir] Directorio: $TARGET_DIR"
|
||||
echo "[topdir] Algoritmo: $HASH_ALGO"
|
||||
fi
|
||||
|
||||
pushd "$TARGET_DIR" >/dev/null || exit 1
|
||||
|
||||
# Definir snapshot relativo al directorio objetivo o usar el custom
|
||||
@@ -131,17 +138,27 @@ else
|
||||
pushd "$TARGET_DIR" >/dev/null || exit 1
|
||||
fi
|
||||
|
||||
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
|
||||
echo "[topdir] Snapshot: $SNAPSHOT_FILE"
|
||||
fi
|
||||
|
||||
# Leer patrones de exclusión desde archivo si existe
|
||||
if [[ -n "$IGNORE_FILE" && -f "$IGNORE_FILE" ]]; then
|
||||
while IFS= read -r pattern; do
|
||||
[[ -z "$pattern" || "$pattern" == \#* ]] && continue
|
||||
EXCLUDE_PATTERNS+=("$pattern")
|
||||
done < "$IGNORE_FILE"
|
||||
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
|
||||
echo "[topdir] Cargadas ${#EXCLUDE_PATTERNS[@]} exclusiones desde $IGNORE_FILE"
|
||||
fi
|
||||
elif [[ -f ".topdirignore" ]]; then
|
||||
while IFS= read -r pattern; do
|
||||
[[ -z "$pattern" || "$pattern" == \#* ]] && continue
|
||||
EXCLUDE_PATTERNS+=("$pattern")
|
||||
done < ".topdirignore"
|
||||
if [[ "$OUTPUT_FORMAT" == "text" && ${#EXCLUDE_PATTERNS[@]} -gt 0 ]]; then
|
||||
echo "[topdir] Cargadas ${#EXCLUDE_PATTERNS[@]} exclusiones desde .topdirignore"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Construir comando find con exclusiones
|
||||
@@ -171,20 +188,35 @@ for pattern in "${EXCLUDE_PATTERNS[@]}"; do
|
||||
done
|
||||
|
||||
# Generar nuevo snapshot: compute hash para cada archivo regular
|
||||
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
|
||||
echo -n "[topdir] Escaneando archivos..."
|
||||
fi
|
||||
|
||||
file_count=0
|
||||
while IFS= read -r -d '' file; do
|
||||
"$HASH_CMD" "$file"
|
||||
file_count=$((file_count + 1))
|
||||
if [[ "$OUTPUT_FORMAT" == "text" && $((file_count % 100)) -eq 0 ]]; then
|
||||
echo -ne "\r[topdir] Escaneando archivos... $file_count"
|
||||
fi
|
||||
done < <("${find_cmd[@]}" -print0 | sort -z) > "$TMP_NEW"
|
||||
|
||||
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
|
||||
echo -e "\r[topdir] Escaneados $file_count archivos "
|
||||
fi
|
||||
|
||||
# Si no hay snapshot previo, lo creamos y salimos
|
||||
if [[ ! -f "$SNAPSHOT_FILE" ]]; then
|
||||
mv "$TMP_NEW" "$SNAPSHOT_FILE"
|
||||
|
||||
case "$OUTPUT_FORMAT" in
|
||||
text)
|
||||
echo "Snapshot creado en '$SNAPSHOT_FILE' (no había ejecución previa)."
|
||||
echo "[topdir] ✓ Snapshot creado en '$SNAPSHOT_FILE'"
|
||||
echo "[topdir] ✓ $file_count archivos registrados"
|
||||
echo "[topdir] Primera ejecución completada. Ejecuta nuevamente para detectar cambios."
|
||||
;;
|
||||
json)
|
||||
echo '{"status":"snapshot_created","snapshot_file":"'"$SNAPSHOT_FILE"'","new":[],"modified":[],"deleted":[]}'
|
||||
echo '{"status":"snapshot_created","snapshot_file":"'"$SNAPSHOT_FILE"'","files_tracked":'"$file_count"',"new":[],"modified":[],"deleted":[]}'
|
||||
;;
|
||||
csv)
|
||||
echo "status,path"
|
||||
@@ -197,6 +229,10 @@ fi
|
||||
|
||||
# Convertir snapshot antiguo y nuevo a formato: <path>\t<checksum>
|
||||
# Convertir líneas "checksum path" a formato "path<TAB>checksum" de forma robusta
|
||||
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
|
||||
echo "[topdir] Comparando con snapshot anterior..."
|
||||
fi
|
||||
|
||||
sed -E 's/^[[:space:]]*([0-9a-f]+)[[:space:]]+(.*)$/\2\t\1/' "$SNAPSHOT_FILE" > "$TMP_OLD" 2>/dev/null || true
|
||||
sed -E 's/^[[:space:]]*([0-9a-f]+)[[:space:]]+(.*)$/\2\t\1/' "$TMP_NEW" > "$TMP_NEW.sorted"
|
||||
mv "$TMP_NEW.sorted" "$TMP_NEW"
|
||||
@@ -229,29 +265,41 @@ done < "$TMP_OLD.changes"
|
||||
# Mostrar informe según formato
|
||||
case "$OUTPUT_FORMAT" in
|
||||
text)
|
||||
echo "Informe de comparación para: $TARGET_DIR"
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo " INFORME DE CAMBIOS"
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo "Directorio: $TARGET_DIR"
|
||||
echo "Archivos escaneados: $file_count"
|
||||
echo "Nuevos: ${#new_files[@]} | Modificados: ${#modified_files[@]} | Eliminados: ${#delete_files[@]}"
|
||||
echo "───────────────────────────────────────────────────────────────"
|
||||
echo ""
|
||||
if [[ ${#new_files[@]} -eq 0 && ${#modified_files[@]} -eq 0 && ${#delete_files[@]} -eq 0 ]]; then
|
||||
echo "No se detectaron cambios desde la última ejecución."
|
||||
echo "✓ No se detectaron cambios desde la última ejecución."
|
||||
else
|
||||
if [[ ${#new_files[@]} -gt 0 ]]; then
|
||||
echo -e "\nNuevos archivos (${#new_files[@]}):"
|
||||
echo "📄 NUEVOS ARCHIVOS (${#new_files[@]}):"
|
||||
for f in "${new_files[@]}"; do
|
||||
echo " $f"
|
||||
echo " + $f"
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
if [[ ${#modified_files[@]} -gt 0 ]]; then
|
||||
echo -e "\nArchivos modificados (${#modified_files[@]}):"
|
||||
echo "✏️ ARCHIVOS MODIFICADOS (${#modified_files[@]}):"
|
||||
for f in "${modified_files[@]}"; do
|
||||
echo " $f"
|
||||
echo " ~ $f"
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
if [[ ${#delete_files[@]} -gt 0 ]]; then
|
||||
echo -e "\nArchivos eliminados desde último snapshot (${#delete_files[@]}):"
|
||||
echo "🗑️ ARCHIVOS ELIMINADOS (${#delete_files[@]}):"
|
||||
for f in "${delete_files[@]}"; do
|
||||
echo " $f"
|
||||
echo " - $f"
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
;;
|
||||
|
||||
json)
|
||||
@@ -281,7 +329,8 @@ case "$OUTPUT_FORMAT" in
|
||||
done
|
||||
del_json+="]"
|
||||
|
||||
echo "{\"status\":\"ok\",\"directory\":\"$TARGET_DIR\",\"hash\":\"$HASH_ALGO\",\"new\":$new_json,\"modified\":$mod_json,\"deleted\":$del_json}"
|
||||
total_changes=$((${#new_files[@]} + ${#modified_files[@]} + ${#delete_files[@]}))
|
||||
echo "{\"status\":\"ok\",\"directory\":\"$TARGET_DIR\",\"hash\":\"$HASH_ALGO\",\"files_scanned\":$file_count,\"total_changes\":$total_changes,\"new\":$new_json,\"modified\":$mod_json,\"deleted\":$del_json}"
|
||||
;;
|
||||
|
||||
csv)
|
||||
|
||||
Referencia en una nueva incidencia
Block a user