#!/bin/bash #-xf # Backup Strategy version 2.00 made by Marian Boricean, July 2008 # Last update March 2009 # # This script will make (apparent) full backups of a given list of folders # for a specified number of days using 'rsync' tool. # This script gets as the first argument the frequency of the backup # The frequency can be: hourly, daily, weekly, monthly, yearly # The script will manage four consecutive backups (.latest, .0, .1, .2) # # ------Variables--------- SDIR="/home/director1/ /etc/ /home/director3/" # List of directories to backup separated by spaces DDIR="/media/EXTERNAL/director2/" # Where to do the backup. Please use a different phisical disk. LOG=~/tmp/backup.log PID=~/tmp/backup.pid ADMIN=me@mydomain.com EXCLUDFILE="/etc/backup-excludes.txt" RSYNC='/usr/bin/rsync -avhH --progress' DATEFORMAT="%F_%H.%M" BSTIME=$(date +"$DATEFORMAT") # ------Here is where it ends your modifications ------------------------------------ # ------Do not modify what is bellow, unless you want to improve the script --------- # # ------Functions-------------------------------------------------------------------- error () { echo "$0: $@" 1>&2 |tee -a $LOG exit 1 } MOVE () { # Make sure you run as root # if [ `id -u` != 0 ]; then error "You must run this as root"; fi # Swift the backups and create the latest folder if [ -d $DDIR/$1.2 ]; then rm -rf $DDIR/$1.2 fi if [ -d $DDIR/$1.1 ]; then mv $DDIR/$1.1 $DDIR/$1.2 fi if [ -d $DDIR/$1.0 ]; then mv $DDIR/$1.0 $DDIR/$1.1 fi if [ -d $DDIR/$1.latest ]; then mv $DDIR/$1.latest $DDIR/$1.0 mkdir $DDIR/$1.latest fi } BACKUP () { # it can take the following arguments: hourly, daily, weekly, monthly or yearly # Remove the log file rm -f $LOG.$1 # Create the log file anew touch $LOG.$1 # Check if it's an hourly backup if [ $1 = "hourly" ] ; then #Send to the log the start time echo "$1 backup ran $(date +"$DATEFORMAT")" >> $LOG.$1 # Rename the folders from .latest to .0 to .1 to .2 (first delete existing .2) MOVE $1 # Create an empty file with the start time in the destination directory touch $DDIR/$1.latest/---Start-$BSTIME--- # For every folder to backup, perform the rsync, linking to the previous backup. for sdir in $SDIR; do $RSYNC --exclude-from $EXCLUDFILE --link-dest=$DDIR/$1.0 $sdir $DDIR/$1.latest/ 2>&1 | tee -a $LOG.$1 done # Backup finished, create an empty file with the end time. touch $DDIR/$1.latest/--Finish-$(date +"$DATEFORMAT")--- # Copy the log file to the destination folder. cp $LOG.$1 $DDIR/$1.latest/Backup-log.txt # Send email to the admin echo "Check the log file: file://$DDIR/$1.latest/Backup-log.txt" | mail -s "$1 Backup $(hostname)" $ADMIN else # It's not an hourly backup; therefore link to the latest one found echo "$1 backup ran $(date +"$DATEFORMAT" )" >> $LOG.$1 # Does the hourly backup exist? if yes, link to it. if [ -d $DDIR/hourly.latest ] ; then echo "The hourly backup exists; this will be the start point for the $1 backup" | tee -a $LOG.$1 MOVE $1 touch $DDIR/$1.latest/---Start-$BSTIME--- for sdir in $SDIR; do $RSYNC --exclude-from $EXCLUDFILE --link-dest=$DDIR/hourly.latest $sdir $DDIR/$1.latest/ 2>&1 | tee -a $LOG.$1 done touch $DDIR/$1.latest/--Finish-$(date +"$DATEFORMAT")--- cp $LOG.$1 $DDIR/$1.latest/Backup-log.txt echo "Check the log file: file://$DDIR/$1.latest/Backup-log.txt" | mail -s "$1 Backup $(hostname)" $ADMIN else # Does the daily backup exist? if yes, link to it. if [ -d $DDIR/daily.latest ] ; then echo "The daily backup exists; this will be the start point for the $1 backup" | tee -a $LOG.$1 MOVE $1 touch $DDIR/$1.latest/---Start-$BSTIME--- for sdir in $SDIR; do $RSYNC --exclude-from $EXCLUDFILE --link-dest=$DDIR/daily.latest $sdir $DDIR/$1.latest/ 2>&1 | tee -a $LOG.$1 done touch $DDIR/$1.latest/--Finish-$(date +"$DATEFORMAT")--- cp $LOG.$1 $DDIR/$1.latest/Backup-log.txt echo "Check the log file: file://$DDIR/$1.latest/Backup-log.txt" | mail -s "$1 Backup $(hostname)" $ADMIN else # Does the weekly backup exist? if yes, link to it. if [ -d $DDIR/weekly.latest ] ; then echo "The weekly backup exists; this will be the start point for the $1 backup" | tee -a $LOG.$1 MOVE $1 touch $DDIR/$1.latest/---Start-$BSTIME--- for sdir in $SDIR; do $RSYNC --exclude-from $EXCLUDFILE --link-dest=$DDIR/weekly.latest $sdir $DDIR/$1.latest/ 2>&1 | tee -a $LOG.$1 done touch $DDIR/$1.latest/--Finish-$(date +"$DATEFORMAT")--- cp $LOG.$1 $DDIR/$1.latest/Backup-log.txt echo "Check the log file: file://$DDIR/$1.latest/Backup-log.txt" | mail -s "$1 Backup $(hostname)" $ADMIN else # Does the monthly backup exist? if yes, link to it. if [ -d $DDIR/monthly.latest ] ; then echo "The monthly backup exists; this will be the start point for the $1 backup" | tee -a $LOG.$1 MOVE $1 touch $DDIR/$1.latest/---Start-$BSTIME--- for sdir in $SDIR; do $RSYNC --exclude-from $EXCLUDFILE --link-dest=$DDIR/monthly.latest $sdir $DDIR/$1.latest/ 2>&1 | tee -a $LOG.$1 done touch $DDIR/$1.latest/--Finish-$(date +"$DATEFORMAT")--- cp $LOG.$1 $DDIR/$1.latest/Backup-log.txt echo "Check the log file: file://$DDIR/$1.latest/Backup-log.txt" | mail -s "$1 Backup $(hostname)" $ADMIN else # There is no latest backup available. Start from scratch! echo "the latest backup doen't exist. Strting from scratch for $1 backup"| tee -a $LOG.$1 MOVE $1 touch $DDIR/$1.latest/---Start-$BSTIME--- for sdir in $SDIR; do $RSYNC --exclude-from $EXCLUDFILE --link-dest=$DDIR/$1.0 $sdir $DDIR/$1.latest/ 2>&1 | tee -a $LOG.$1 done touch $DDIR/$1.latest/--Finish-$(date +"$DATEFORMAT")--- cp $LOG.$1 $DDIR/$1.latest/Backup-log.txt echo "Check the log file: file://$DDIR/$1.latest/Backup-log.txt" | mail -s "$1 Backup $(hostname)" $ADMIN fi fi fi fi fi } # here is the actual backup # If you don't specify one of the valid variants, complain and exit. # It MUST be one of the following: hourly, daily, weekly, monthly or yearly # first verify if a backup is on-going. If it is, send an email about it and exit. ps -fe | grep -i backup | grep -v grep | grep rsync > $PID if [ -s $PID ] ; then cat $PID | mail -s "$1 backup cannot run. A backup is already in progress" $ADMIN echo "$1 backup cannot run. A backup is already in progress" exit 1 else # There is not backup in progress. Now check if the destination directory exists. if [ -d $DDIR ] ; then case $1 in hourly) BACKUP hourly;; daily) BACKUP daily;; weekly) BACKUP weekly;; monthly) BACKUP monthly;; yearly) BACKUP yearly;; *) echo $1 "is not a valid frequency. You must specify either hourly, daily, monthly or yearly like so " echo "backup.sh hourly" echo "or:" echo "backup.sh monthly"; exit 1 ;; esac else echo "$1 backup cannot run. Destination directory doesn't exist" echo "$1 backup cannot run. Destination directory doesn't exist" | mail -s "$1 backup cannot run" $ADMIN exit 1 fi fi