Easy Linux Backups

As some of you may know, a sad time was had when our Christmas Tree's extra 200W overloaded the breaker that my server was on. Subsequent powerups showed that the server's primary hard disk was indeed toast. I had good backups of all of my important data, but most of the setup data for Courier and Samba were lost. Not too much pain, but it was still a bit irritating to restore.

To whit, I have created a new backup script for my system! I partitioned the new disk straight in half, keeping 40G for the primary partition and 40G for the backup. RAID-1 cries James! Nay, good sir, for I know the perils of RAID as backup. A good backup system shall include days if not weeks of backups that I can go back to and consult should I mire my setup data.

Loe! My new backup script maintains 4 days worth of daily backups, 2 weeks worth of weekly backups and a single monthly backup. I of course burn regular backups, for the times in between. Now, say you, I want to see this backup script that you so gleefully refer to. Well, good sir, here it'tis!


#!/bin/sh
# weekly_backup.sh
# modified: 2008/01/14
# version:  1.0
# history:
# - v1.0
#   Added support for ITEMS_BACKWARDS instead of DAYS backwards, removing
#   the need to compute how many days worth of backups you want.
#

set -e
DIRECTORIES="/bin /etc /home /var /usr"
BASE_DIR="/media/backup"

if [ ! $1 ]; then
  echo "You must pass either \"daily\", \"weekly\", or \"monthly\"."
  exit 0
fi


# -- Initial setup...
case $1 in
  "daily" )
    ITEMS_BACKWARDS=4;;
  "weekly" )
    ITEMS_BACKWARDS=2;;
  "monthly" )
    ITEMS_BACKWARDS=1;;
  * )
    echo "Invalid argument."
    echo "  You must pass either \"daily\", \"weekly\", or \"monthly\"."
    exit 1;;
esac

# -- Run the backup...
DATEF=`date +%Y-%m-%d`
TARGET="$BASE_DIR/$1/$DATEF"

mkdir -p $TARGET
for i in $DIRECTORIES; do (
  rsync -avz $i $TARGET
); done

# -- Remove old backups...
ITEMS=`find $BASE_DIR/$1 -maxdepth 1 | egrep "[0-9]{4}\-[0-9]{2}\-[0-9]{2}" | wc -l`
if [ $ITEMS -gt $ITEMS_BACKWARDS ]; then
  TO_REMOVE=`expr $ITEMS - $ITEMS_BACKWARDS`
  echo "$TO_REMOVE items will be removed."
  for i in `find $BASE_DIR/$1 -maxdepth 1 | egrep "[0-9]{4}\-[0-9]{2}\-[0-9]{2}" | sort -r| tail -n$TO_REMOVE`; do (
    rm -rf $i
  ); done
fi

This script gets called by the following cron structure daily, weekly and monthly:


# m h  dom mon dow   command
  1 2  *   *   *     bash /usr/local/bin/backup.sh daily
  1 3  */7 *   *     bash /usr/local/bin/backup.sh weekly
  1 4  1   *   *     bash /usr/local/bin/backup.sh monthly

Then I end up with lovely, delicious and fresh backups in /media/backup/{daily,weekly,monthly}. Om noms!



Required
For gravatar support
Required