#!/usr/bin/env bash #et -x # On using rsync for really efficient backups: # http://www.mikerubel.org/computers/rsync_snapshots/ # On setting up a windows machine with an rsync daemon (service) : # http://www.gaztronics.net/rsync.php set -u export PATH=/bin:/usr/bin:/sbin:/usr/sbin USE_COMPRESSION=false RSYNC_OPTS="" VERBOSE=0 if tty -s then ON_TTY=true #TTY_OPTS="-v --progress --stats" TTY_OPTS="--progress --stats" else ON_TTY=false TTY_OPTS="--stats" fi while [ "$#" -ge 1 ] do case "$1" in --rsync-opts) RSYNC_OPTS="$2" shift ;; --srcdir) SRCDIR="$2" shift ;; --dstdir) DSTDIR="$2" shift ;; --num-to-keep) NUM_TO_KEEP="$2" shift ;; --verbose) VERBOSE=$[$VERBOSE+1] ;; --use-compression) USE_COMPRESSION=true ;; --dan) SRCDIR=/big DSTDIR=/backups/dan-rsync-backups NUM_TO_KEEP=60 USE_COMPRESSION=false ;; --gg) SRCDIR=rsync://192.168.1.201/GG DSTDIR=/backups/gg-rsync-backups NUM_TO_KEEP=60 #USE_COMPRESSION=true # Guangyu's machine tends to overheat if we enable compression USE_COMPRESSION=false ;; *) echo "$0: Illegal option: $1" 1>&2 exit 1 ;; esac shift done if [ "${SRCDIR:-''}" = "" ] then echo Sorry, you must give a source directory with --srcdir fi if [ "${DSTDIR:-''}" = "" ] then echo Sorry, you must give a destination directory with --dstdir fi if [ "$USE_COMPRESSION" = true ] then COMPRESS_FLAG=-z else COMPRESS_FLAG="" fi if ! mkdir -p "$DSTDIR" then echo Sorry, mkdir -p "$DSTDIR" failed 1>&2 exit 1 fi if ! cd "$DSTDIR" then echo Sorry, cd "$DSTDIR" failed 1>&2 exit 1 fi if [ -d backup."$NUM_TO_KEEP" ] then # make room for some sliding, if the last directory already exists rm -rf backup."$NUM_TO_KEEP" fi if [ -d "backup.1.complete" ] then # slide them up a notch for backup_no in $(seq $[$NUM_TO_KEEP-1] -1 1) do if [ "$VERBOSE" -ge 1 ] then echo Checking backup $backup_no... fi if [ -d "backup.$backup_no.complete" ] then if [ "$VERBOSE" -ge 1 ] then echo Sliding backup $backup_no... fi backup_no_plus_1="$[$backup_no+1]" mv "backup.$backup_no.complete" "backup.$backup_no_plus_1.complete" if [ -d "backup.$backup_no" ] then ( echo "Both backup.$backup_no and backup.$backup_no.complete detected" echo "Will keep backup.$backup_no.complete, but delete backup.$backup_no" ) 1>&2 rm -rf "backup.$backup_no" fi fi done if ! mkdir backup.1 then echo Sorry, mkdir backup.1 failed 1>&2 exit 1 fi elif [ -d backup.1 ] then ( echo "Incomplete backup detected - instead of sliding backups up a notch, instead" echo "we'll try to get a complete backup using the prior incomplete one as" echo "a starting point..." ) 1>&2 else if ! mkdir backup.1 then echo Sorry, mkdir backup.1 failed 1>&2 exit 1 fi fi echo "Backing up $SRCDIR to $DSTDIR..." 1>&2 rsync \ $RSYNC_OPTS \ -a \ $TTY_OPTS \ $COMPRESS_FLAG \ --delete \ --link-dest=../backup.2.complete "$SRCDIR"/ backup.1 rsync_exit_status="$?" # 24 means a file vanished from the initial file list before it could be transferred, but that's OK. # 23 means some files couldn't be transferred - EG, because some pathnames were too long. case "$rsync_exit_status" in 0|23|24) mv backup.1 backup.1.complete ;; *) echo rsync failed with exit status "$rsync_exit_status", not "mv'ing" ;; esac