Yet another rsync based backup script

Yet another rsync based backup script

Just putting this here for easy reference, or to help any random passers by. I know there are tools that are supposed to automate this like rsnapshot but I was disappointed to see that rsnapshot is probably unmaintained

On top of that, this looked like something easy enough to roll my own and adapt to my needs. So there you go...

#!/bin/bash
# A script to perform daily/weekly/monthly backups using rsync

SOURCE="user@remote:/path/some_files" DESTINATION="/backups/my_backups"

How many backups of each type shall we keep?

DAILY_COUNT=7 WEEKLY_COUNT=4 MONTHLY_COUNT=18

DAILY=$(date "+daily_%Y_%m_%d") WEEKLY=$(date "+weekly_%Y_%W") MONTHLY=$(date "+monthly_%Y_%m") ARCHIVE="archive" LATEST="latest"

set -e

Make sure destination dirs exist

mkdir -p "${DESTINATION}/${ARCHIVE}" mkdir -p "${DESTINATION}/${LATEST}"

cd "${DESTINATION}"

ABS_LATEST="$(pwd)/${LATEST}"

Do the rsync

rsync -a –quiet –delete –link-dest="${ABS_LATEST}" – "${SOURCE}" "${ARCHIVE}/${DAILY}"

Replace the last latest

/bin/rm -rf – "${ABS_LATEST}" /bin/cp -al – "${ARCHIVE}/${DAILY}" "${ABS_LATEST}"

Add new weekly if needed

if [ ! -d "${ARCHIVE}/${WEEKLY}" ]; then /bin/cp -al – "${ABS_LATEST}" "${ARCHIVE}/${WEEKLY}" fi

Add new monthly if needed

if [ ! -d "${ARCHIVE}/${MONTHLY}" ]; then /bin/cp -al – "${ABS_LATEST}" "${ARCHIVE}/${MONTHLY}" fi

Cull archives

cd "${ARCHIVE}"

Daily culling

/usr/bin/find . -maxdepth 1 -type d -regextype posix-egrep
-regex ".*/daily_[0-9]{4}[0-9]{2}[0-9]{2}" -printf "%f\n" | sort -r | tail -n +$((${DAILY_COUNT} + 1)) | while read EXPIRED; do #echo "Removing ${EXPIRED}" /bin/rm -rf – "$EXPIRED" done

Weekly culling

/usr/bin/find . -maxdepth 1 -type d -regextype posix-egrep
-regex ".*/weekly_[0-9]{4}_[0-9]{2}" -printf "%f\n" | sort -r | tail -n +$((${WEEKLY_COUNT} + 1)) | while read EXPIRED; do #echo "Removing ${EXPIRED}" /bin/rm -rf – "$EXPIRED" done

Monthly culling

/usr/bin/find . -maxdepth 1 -type d -regextype posix-egrep
-regex ".*/monthly_[0-9]{4}_[0-9]{2}" -printf "%f\n" | sort -r | tail -n +$((${MONTHLY_COUNT} + 1)) | while read EXPIRED; do #echo "Removing ${EXPIRED}" /bin/rm -rf – "$EXPIRED" done