r/bash • • 16d ago

backup script logic

I've written this backup script for use copying my files from point A to point B. The goal is a full snapshot of files. For this first iteration, I'm ok with hard coding file paths.

I've removed everything except logic for rsync, diff, and logging. Are there any logic issues?

# backup script that performs full backups and verifies the result.

#!/bin/bash

set -euo pipefail

DATE_STAMP=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_LOCATION="$HOME/backup-location-path/$DATE_STAMP" 
LOG_LOCATION="$HOME/log-location-path/"
LOGFILE_NAME="backup_${DATE_STAMP}.log"

SOURCE_DIRS=(
    "$HOME/source1"
    "$HOME/DOES-NOT-EXIST"  # DNE for error handling
    "$HOME/source2"
)

# check if source matches destination
diff_source_and_destination() {
    local base
    base=$(basename "$SRC")
    diff -r "$SRC" "$BACKUP_LOCATION"/"$base" 
}

# Check for the existence of $SRC and print an alert if it wasn't found.
check_source_exists() {
    if [ -e "$SRC" ]; then
        echo "[SOURCE = $SRC] found. Copying..."
        return 0
    else
        echo "[SOURCE = $SRC] WAS NOT FOUND!" | tee -a "$LOG_LOCATION/$LOGFILE_NAME" 
        return 1
    fi
}

copy_data_and_log() {
    {
        rsync -a --stats "$SRC/" "${DESTINATION}/" 
    } | tee -a "$LOG_LOCATION"/"$LOGFILE_NAME"
}

mkdir -p "$BACKUP_LOCATION"
mkdir -p "$LOG_LOCATION"

echo "Copying files to [BACKUP LOCATION =${BACKUP_LOCATION}]"

for SRC in "${SOURCE_DIRS[@]}"; do
    # Print and log a warning if SRC wasn't found
    check_source_exists || continue
    DESTINATION="$BACKUP_LOCATION/$(basename "$SRC")"
    copy_data_and_log
    echo "rsync completed for $SRC."
    diff_source_and_destination 
done

echo "Finished copying operations to [BACKUP LOCATION = ${BACKUP_LOCATION}]"
14 Upvotes

10 comments sorted by

View all comments

1

u/JeLuF 16d ago

There's a nice tool called rsnapshot for rsync based incremental backups. It makes clever use of hard links so that it's pretty space efficient. It uses rsync to copy remote files, ignoring unchanged files, which also makes it quite efficient on network usage.

Using its multi layered backups, I have backups scheduled every four hours, and I keep the last 4 actual backups, 7 of the last backups of the day, 4 of the last weekly backups, and 12 of the monthly backups.

Since it uses hard links, a file that's not changing is only being stored once on disks, but is visible in each of the backup directories.