Simple Rolling Backup Script

I was looking for ways to do incremental backups with rsync, and all I could find were scripts that pretty much push down a stack e.g. backup.0 backup.1 backup.2 etc but I didn’t like how that works for daily backups. Instead, I modified the idea to go the other way and do backups into Day folders e.g. ‘monday’, ‘tuesday’, etc. Being organized this way, it’s easy to find a change that happened last Thursday, for example. Each day, before it runs the update, it also pushes what’s in that day’s folder (from the previous week) into a ‘lastweek’ folder, and on the first Monday of the month, it’ll push the preious Monday’s data into a ‘lastmonth’ folder. Deleted files on the server are also kept in a separate directory, inside each day’s folder. The entire folder tree is served up on a samba server, read only, so users can find old versions of files if they need to. Every time it runs, it creates hard links of existing files, so the only actual copies of files are whatever files get modified, or added between executions.

#!/bin/bash

TODAY=$(date +%A | tr '[:upper:]' '[:lower:]')
YESTERDAY=$(date --date="yesterday" +%A | tr '[:upper:]' '[:lower:]')
DAYOFMONTH=$(date +%d)
REMOTEDIR="root@x.x.x.x:/srv/external/workfiles"
BACKUPDIR="/srv/external/rollingBackup/"
LASTRUN="no-date"
TODAYDATE=$(date +%D)
cd $BACKUPDIR

#check if there was a previous run date present
if [ -a $BACKUPDIR/$TODAY/backup-date.txt ]
then
    LASTRUN=$(cat $BACKUPDIR/$TODAY/backup-date.txt)
fi

# create folders if they dont exist yet
if [ ! -d sunday ]
then
    mkdir sunday
fi

if [ ! -d monday ]
then
    mkdir monday
fi

if [ ! -d tuesday ]
then
    mkdir tuesday
fi

if [ ! -d wednesday ]
then
    mkdir wednesday
fi

if [ ! -d thursday ]
then
    mkdir thursday
fi

if [ ! -d friday ]
then
    mkdir friday
fi

if [ ! -d saturday ]
then
    mkdir saturday
fi

if [ ! -d lastweek ]
then
    mkdir lastweek
fi

if [ ! -d lastmonth ]
then
    mkdir lastmonth
fi

if [ $TODAY == monday ]
then
    if [ $LASTRUN != $TODAYDATE ]
    then
        if [ $DAYOFMONTH -lt 8 ]
        then
            if [ -z "$(ls -A ./lastweek)" ]
            then
                echo "Last week is empty, so don't remove last month"
            else
                echo "First week of the month, move 'lastweek' to 'lastmonth'"
                rm -Rf ./lastmonth/*
                cp -al ./lastweek/* ./lastmonth/
            fi
        fi
        if [ -z "$(ls -A ./$TODAY)" ]
        then
            echo "Today's folder is empty, so don't empty last week's folder"
        else
            echo "Moving 'monday' to 'lastweek' before update"
            rm -Rf ./lastweek/*
            cp -al ./$TODAY/* ./lastweek/
        fi
        echo "Copy 'yesterday' to 'today', but remove yesterday's deleted files from today"
        rm -Rf ./$TODAY/*
        cp -al ./$YESTERDAY/* ./$TODAY/
        rm -Rf ./$TODAY/deleted_files
    fi
    echo "Starting rsync..."
    rsync -avp --delete --backup --backup-dir=$BACKUPDIR/$TODAY/deleted_files -e 'ssh' $REMOTEDIR $BACKUPDIR/$TODAY
    rm ./$TODAY/backup-date.txt
    rm ./$TODAY/backup-time.txt
    date +%D > ./$TODAY/backup-date.txt
    date +%T > ./$TODAY/backup-time.txt
else
    if [ $LASTRUN != $TODAYDATE ]
    then
        if [ -z "$(ls -A ./$TODAY)" ]
        then
            echo "Today's folder is empty, so don't empty last week's folder"
        else
            echo "Moving '$TODAY' to 'lastweek'"
            rm -Rf ./lastweek/*
            cp -al ./$TODAY/* ./lastweek/
        fi
        echo "Copy 'yesterday' to 'today', but remove yesterday's deleted files from today"
        rm -Rf ./$TODAY/*
        cp -al ./$YESTERDAY/* ./$TODAY/
        rm -Rf ./$TODAY/deleted_files
    fi
    echo "Starting rsync..."
    rsync -avp --delete --backup --backup-dir=$BACKUPDIR/$TODAY/deleted_files -e 'ssh' $REMOTEDIR $BACKUPDIR/$TODAY
    rm ./$TODAY/backup-date.txt
    rm ./$TODAY/backup-time.txt
    date +%D > ./$TODAY/backup-date.txt
    date +%T > ./$TODAY/backup-time.txt
fi

So far, it appears to work as expected, but I won’t know for sure until it has ran a while without any problems.

Leave a comment

Design a site like this with WordPress.com
Get started