#!/bin/bash # Purge files from the backup trash directory. # # Usage: # ./purge-backup-trash.sh [--dry-run] # # Environment: # TRASH_DIR=/backup/trash Directory containing trash files to purge # DRY_RUN=false If true, only report what would be deleted set -euo pipefail BASEPATH="$(cd "$(dirname "$0")" && pwd)" # shellcheck source=volume-utils.sh source "$BASEPATH/volume-utils.sh" TRASH_DIR="${TRASH_DIR:-/backup/trash}" DRY_RUN=false if [[ "${1:-}" == "--dry-run" ]]; then DRY_RUN=true elif [[ -n "${1:-}" ]]; then echo "Usage: $0 [--dry-run]" >&2 exit 1 fi log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2 } # Main purge function purge_trash() { local total_bytes=0 local file_count=0 local delete_list=() if [[ ! -d "$TRASH_DIR" ]]; then log "Trash directory does not exist: $TRASH_DIR" echo "0 0" return fi # Find all files in the trash directory and build delete list with FULL paths while IFS= read -r -d '' file; do # Use full path, not just basename, to avoid stat() looking in wrong directory delete_list+=("$file") done < <(find "$TRASH_DIR" -maxdepth 1 -type f -print0 2>/dev/null) # Process each file with full path for file in "${delete_list[@]}"; do if [[ ! -f "$file" ]]; then continue fi local size size=$(stat -c%s "$file" 2>/dev/null || echo 0) total_bytes=$((total_bytes + size)) file_count=$((file_count + 1)) if $DRY_RUN; then log "DRY-RUN would purge: $file (${size} bytes)" else rm -f -- "$file" log "Purged: $file (${size} bytes)" fi done echo "$file_count $total_bytes" } main() { log "Starting trash purge from $TRASH_DIR (dry_run=$DRY_RUN)" local count bytes read -r count bytes < <(purge_trash) local bytes_human bytes_human=$(numfmt --to=iec-i --suffix=B "$bytes" 2>/dev/null || echo "${bytes}B") log "Trash purge complete: deleted=$count files, freed≈$bytes_human" } main "$@"