#!/bin/bash # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # 2017-01-06-SRJ # For information on how this script works, and what it does, read the # file README in this folder # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # # suggestion from H. Milz: avoid accidental use of $PATH unset PATH # # =-=-=-=- System commands used by this script. -=-=-=-=-=-=-=-= ID=/usr/bin/id; ECHO=/bin/echo; MOUNT=/bin/mount; RM=/bin/rm; MV=/bin/mv; CP=/bin/cp; TOUCH=/bin/touch; RSYNC=/usr/bin/rsync; DATE=/bin/date; WC=/usr/bin/wc; CAT=/bin/cat; TAIL=/usr/bin/tail; HEAD=/usr/bin/head; GREP=/bin/grep; CHMOD=/bin/chmod # =-=-=-=-=-=-=- Make sure we're running as root -=-=-=-=-=-=-=-=-= if (( `$ID -u` != 0 )); then { $ECHO "Sorry, must be root. Exiting..."; exit; } fi; # =-=-=-=-=-=-=-=-=-=- Read in the Variables -=-=-=-=-=-=-=-=-=-=-= if [ ! -e $1 ] ; then { $ECHO "No viable config file given."; exit 0 } fi; # If we're here, there must be a config file to read, the line below # reads the variables from that file into this bash environment. . $1 # # # Update 2017-01-01 SRJ The line above sources the variables from # # # the config file into this script - see /Backup/00-System.conf # # # for more information. # Make sure that the folder list exists, create it if needed; if [ ! -f $SNAPSHOT_RW/Backups ] ; then { $ECHO Nothing >> $SNAPSHOT_RW/Backups } fi; # The full name of the oldest snapshot, first line in Backups [ $($CAT $SNAPSHOT_RW/Backups | $WC --lines) -ge $NUM_SNAP ] && \ OLDEST=$($HEAD -1 $SNAPSHOT_RW/Backups) || OLDEST="Nothing" # The full name of the last snapshot, last line in Backups LAST=$($TAIL -1 $SNAPSHOT_RW/Backups) # The full name of the snapshot for this itteration. (2006-06-22-09-47) CURRENT=$SNAPSHOT_RW/$($DATE +%F-%H-%M) # What time is it, in seconds past the epoch? StartTime=$($DATE +%s) # Hour, minute, second function; _hms() { local S=${1} # this S is used only in this sub-routine ((h=S/3600)) # fills h with the integer of seconds / 3600 ((m=S%3600/60)) # fills m with the integer of the modula from above / 60 ((s=S%60)) # fills s with the integer of seconds / 60 printf "%02d:%02d:%02d\n" $h $m $s # print 2 digit zero padded numbers } # =-=-=-=-=-=-=-=-=- The script itself. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # I stopped mounting and unmounting the filesystem, I now do this by # hand on an as-needed basis - these backup scripts are now on the # backup drives themselves. # Attempt to remount the RO mount point as RW; else abort # $MOUNT -o remount,rw $MOUNT_DEVICE $MOUNT_DIR ; # if (( $? )); then { # $ECHO "Could not remount $MOUNT_DIR read-write"; exit; # } fi; # Creating the snapshot. # Delete the oldest snapshot, if it exists: if [ -e ${OLDEST} ] ; then { $RM -rf ${OLDEST} ;} fi ; # Delete the last filelist and create a new one with proper permissions. if [ -f $FILELIST ] ; then { $RM -f $FILELIST ;} fi ; $TOUCH $FILELIST ; $CHMOD 600 $FILELIST # Rsync from the system into the latest snapshot (notice that rsync # behaves like cp --remove-destination by default, so the destination is # unlinked first. If it were not so, this would copy over the other # snapshot(s) too! RSARGS=" --archive --verbose --delete --delete-excluded --numeric-ids \ --modify-window=1 --hard-links --one-file-system --acls --xattrs \ --exclude-from="$EXCLUDES" --link-dest=$LAST/ " # This is the line that does everything we're doing here... $RSYNC $RSARGS $SNAP_DIR $CURRENT >> $FILELIST; # Add today's snapshot to the list, and remove the oldest; $ECHO $CURRENT >> $SNAPSHOT_RW/Backups $GREP -v $OLDEST $SNAPSHOT_RW/Backups >> $SNAPSHOT_RW/$$.tmp $MV -f $SNAPSHOT_RW/$$.tmp $SNAPSHOT_RW/Backups EndTime=$($DATE +%s) ; ElapsedTime=$(( $EndTime - $StartTime )) TimeWellSpent=$( _hms ${ElapsedTime}) # Write out the summary file. $HEAD -2 $FILELIST > $SUMMARY; $ECHO $(( $($GREP -ve /$ $FILELIST | $WC --lines )-5)) \ New files backed up. >> $SUMMARY $ECHO $OLDEST was removed and $CURRENT was created >> $SUMMARY $ECHO Elapsed time: $TimeWellSpent >> $SUMMARY $TAIL -3 $FILELIST >> $SUMMARY $MV $FILELIST $CURRENT # And thats it for SNAP_DIR. Now remount the RW snapshot mountpoint as RO # $MOUNT -o remount,ro $MOUNT_DEVICE $MOUNT_DIR ; # if (( $? )); then { # $ECHO "Could not remount $MOUNT_DIR readonly"; exit; # } fi;