backup-tank-2.shon commit add sitemap generator (de26b28)
   1#!/bin/bash
   2
   3MOUNT_POINT_PREFIX="/mnt/backup"
   4TEST=1
   5DEBUG=1
   6
   7# Check if the CSV file is provided
   8if [ "$#" -ne 1 ]; then
   9    echo "Usage: $0 <path_to_csv_file>"
  10    exit 1
  11fi
  12
  13CSV_FILE="$1"
  14
  15# Declare associative arrays to hold paths and rsync command for each drive
  16declare -A INCLUDE_PATHS
  17declare -A EXCLUDE_PATHS
  18declare -A RSYNC_CMDS
  19
  20if [ $TEST -eq 1 ]; then
  21    echo "Reading index $CSV_FILE"
  22fi
  23
  24# Read the CSV file line by line
  25while IFS=',' read -r FILE_PATH DRIVE _; do
  26    # Trim whitespace
  27    FILE_PATH=$(echo "$FILE_PATH" | xargs)
  28    DRIVE=$(echo "$DRIVE" | xargs)
  29
  30    # Check if row is commented with a #
  31    if [[ "$FILE_PATH" == "#"* ]]; then
  32        continue
  33    fi
  34
  35    # Check if path begins with a slash
  36    if [[ "$FILE_PATH" != /* ]]; then
  37      echo "File path $FILE_PATH is not relative - exiting"
  38      exit 1
  39    fi
  40
  41    # Determine the actual drive path
  42    if [[ "$DRIVE" =~ ^- ]]; then
  43        # Exclusion case
  44        DRIVE=${DRIVE:1}  # Remove the leading '-'
  45        EXCLUDE_PATHS["$FILE_PATH"]=1
  46    else
  47        # Inclusion case
  48        INCLUDE_PATHS["$FILE_PATH"]="$DRIVE"
  49        RSYNC_CMDS["$DRIVE"]=""
  50    fi
  51done < "$CSV_FILE"
  52
  53
  54# Now process the paths to copy
  55for FILE_PATH in "${!INCLUDE_PATHS[@]}"; do
  56    DRIVE="${INCLUDE_PATHS[$FILE_PATH]}"
  57    MOUNT_POINT="$MOUNT_POINT_PREFIX$DRIVE"
  58
  59    # Check if the mount point exists
  60    if [[ $TEST -eq 0 && $(mountpoint -q "$MOUNT_POINT") ]]; then
  61        echo "Nothing mounted to $MOUNT_POINT - skipping $FILE_PATH"
  62        continue
  63    fi
  64
  65    # Check if the path is excluded
  66    if [[ -n "${EXCLUDE_PATHS[$FILE_PATH]}" ]]; then
  67        echo "Excluding $FILE_PATH"
  68        continue
  69    fi
  70
  71    # Get parent directory
  72    PARENT="$(dirname "$FILE_PATH")"
  73    MKDIR_CMD="mkdir -p $MOUNT_POINT$PARENT"
  74    if [ $DEBUG -eq 1 ]; then
  75            echo "$MKDIR_CMD"
  76    if [ $TEST -eq 0 ]; then 
  77            eval "$MKDIR_CMD"
  78    fi
  79
  80    # Check if the path is a directory
  81    EXCLUDE_ARGS=()
  82    if [ -d "$FILE_PATH" ]; then
  83      for EXCLUDE_PATH in "${!EXCLUDE_PATHS[@]}"; do
  84        if [[ "$EXCLUDE_PATH" =~ ^"$FILE_PATH"* ]]; then
  85          if [ -d "$EXCLUDE_PATH" ] && [[ ! "$EXCLUDE_PATH" =~ /$ ]]; then
  86            EXCLUDE_ARGS+=("--exclude=\"$EXCLUDE_PATH/\"")
  87          else
  88            EXCLUDE_ARGS+=("--exclude=\"$EXCLUDE_PATH\"")
  89          fi
  90          if [[ $TEST -eq 1 ]]; then
  91            echo "Excluding $EXCLUDE_PATH from $FILE_PATH"
  92          fi
  93        fi
  94      done
  95    fi
  96    RSYNC_CMD="rsync -Par"
  97    if [[ $TEST -eq 1 ]]; then
  98      RSYNC_CMD+="vn"
  99    if [[ $DEBUG -eq 0 ]]; then
 100      RSYNC_CMD+="q"
 101    fi
 102    RSYNC_CMD+=" "${EXCLUDE_ARGS[@]}" \"$FILE_PATH\" \"$MOUNT_POINT$PARENT/\""
 103    if [[ -n "${RSYNC_CMDS[$DRIVE]}" ]]; then
 104      RSYNC_CMDS["$DRIVE"]+=" & $RSYNC_CMD"
 105    else
 106      RSYNC_CMDS["$DRIVE"]="$RSYNC_CMD"
 107    fi
 108done
 109
 110for DRIVE in "${!RSYNC_CMDS[@]}"; do
 111  if [[ $DEBUG -eq 1 ]]; then
 112    echo "${RSYNC_CMDS[$DRIVE]}"
 113  fi
 114  if [[ $TEST -eq 0 ]]; then
 115    eval "${RSYNC_CMDS[$DRIVE]}" &
 116  fi
 117done
 118
 119wait
 120
 121echo ""
 122
 123for DRIVE in "${!RSYNC_CMDS[@]}"; do
 124  DRIVE_SERIAL="$(lsblk -o MOUNTPOINT,SERIAL | awk -v target="$MOUNT_POINT_PREFIX$DRIVE" '$1 == target { getline; print $1; exit }')"
 125  echo "-------------------------------------------"
 126  echo "Backup summary for Cold Backup Drive $DRIVE"
 127  echo "-------------------------------------------"
 128  echo ""
 129  echo "S/N $DRIVE_SERIAL"
 130  echo "Backup finished $(date)"
 131  echo ""
 132  for FILE_PATH in "${!INCLUDE_PATHS[@]}"; do
 133    if [[ "${INCLUDE_PATHS[$FILE_PATH]}" == "$DRIVE" ]]; then
 134      echo "$FILE_PATH ("$(du -sh "$FILE_PATH" 2>/dev/null | cut -f1)")"
 135      if [ -d "$FILE_PATH" ]; then
 136        for EXCLUDE_PATH in "${!EXCLUDE_PATHS[@]}"; do
 137          if [[ "$EXCLUDE_PATH" =~ ^"$FILE_PATH"* ]]; then
 138            echo "    Excluding .${EXCLUDE_PATH:${#FILE_PATH}} ($(du -sh "$EXCLUDE_PATH" 2>/dev/null | cut -f1))"
 139          fi
 140        done
 141      fi
 142    fi
 143  done
 144  echo ""
 145  echo ""
 146done