#!/bin/bash ######################################################## # autoBackupToUSB.sh - Version 1.5 (2019-01-19) # by Axel Werner [axel.werner.1973@gmail.com] # free to use for personal use. NO COMMERCIAL USE ALLOWED! # Patches and Improvements are welcome. # # this is a cronjob script for install at /etc/crontab # and to be run as root. Its intension is to autodetect # one or more hot plugable backup hard-disks (e.g. USB block devices) # with a specific given Filesystem Label. e.g. BACKUP1 or # BACKUP2. If a backup drive has been detected the drive # will be automatically mounted under /mnt with the # name of the Label and a rsync will be started to backup # all Data from $sourceDir to the given backup drive. # # WARNING: # It is asumed that the backup drives are used as # whole and do not contain any other data than just the # data to be backed up. the backup drives are supposed to # act like a 1:1 mirror of the sourceDir. Any additional # files on the backup drives WILL BE DELETED when this # script is started. # # Use at your own risk. # ######################################################## set -e #debugEnabled=true maxNoBackupDrives=12 validBackupDrives=$( eval echo /dev/disk/by-label/BACKUP{$(seq -s ',' 1 ${maxNoBackupDrives})}) scriptName=$(basename $0) lockFile="/var/run/${scriptName}.lock" sourceDir="/mnt/yourValuableDataHere/" logFile="/var/log/${scriptName}.log" # define some colors for console output RED='\033[91m' YELLOW='\033[93m' GREEN='\033[92m' BLUE='\033[96m' NOCOLOR='\033[0m' NC=$NOCOLOR function getTime { echo $(date +%F-%H%M%S) } function print { echo -e "$@" | tee -a "${logFile}" } function printInfo { echo -e "$NC""$@""$NC" | tee -a "${logFile}" } function printWarning { echo -e "$YELLOW""$@""$NC" | tee -a "${logFile}" } function printError { echo -e "$RED""$@""$NC" | tee -a "${logFile}" >&2 } function printDebug { if test -v debugEnabled ; then echo -e "$BLUE""DEBUG: $(getTime) $@""$NC" | tee -a "${logFile}" fi } function unmount { if umount -l "$mountPoint" ; then printDebug "unmounting successfull." printDebug "removing mountpoint $mountPoint ..." rmdir "$mountPoint" printDebug "removing lock file $lockFile ..." rm "$lockFile" else printError "ERROR: Failed to unmount '$mountPoint'. Aborting." printError $(mount | grep /mnt) printError $(lsof) printError "ERROR: Leaving lock file behind to prevent another rerun." exit -1 fi } printDebug "Checking if $scriptName is already running..." if test -f "$lockFile" ; then printDebug "$scriptName seems already running. Exiting." printDebug $(ls -la "$lockFile") exit -1 else printDebug "creating lockFile '$lockFile' ..." echo $$ > "$lockFile" fi if ! test -x /usr/bin/pv ; then printError "ERROR: /usr/bin/pv not found. make sure you have 'pipe view' installed." exit -1 fi printDebug "Checking if a valid backup drive is connected ..." printDebug "\$validBackupDrives = $validBackupDrives" for drive in $validBackupDrives ; do printDebug "Drive to test next = $drive" if test -b "$drive" ; then printDebug "Valid Backup Drive \"$(basename $drive)\"found." backupDrive="$drive" break fi done if test -z "$backupDrive" ; then printDebug "NO Backup Drive found. Aborting." printDebug "removing lock file $lockFile ..." rm "$lockFile" exit 0 fi mountPoint=/mnt/"$(basename $backupDrive)" mkdir -p "$mountPoint" if ! mount "$backupDrive" "$mountPoint" ; then printError "ERROR: mounting the backup drive '$backupDrive' on mountpoint '$mountPoint' failed." exit -1 fi printDebug "DEBUG: recent mount table:" printDebug $( mount | grep /mnt ) todaysDate=$(date +%F) printDebug "Checking for min. age of backup ..." if test -e "$mountPoint/$scriptName-dateOfBackup-$todaysDate" ; then printDebug "Seems the Backup already had run today. Skipping until tomorrow." printDebug "DEBUG: ls -la $mountPoint" printDebug $( ls -la "$mountPoint" ) unmount exit fi if test -f "$mountPoint/$scriptName-dateOfBackup-*" ; then rm "$mountPoint/$scriptName-dateOfBackup-*" fi printDebug "rsyncing source to destination..." rsync_param="-av --delete-before --delete-excluded --exclude='.Trash-1000/'" rsync $rsync_param "$sourceDir" "$mountPoint" | \ pv -lep -s $(rsync $rsync_param -n \ "$sourceDir" "$mountPoint" | awk 'NF' | wc -l) touch "$mountPoint/$scriptName-dateOfBackup-$todaysDate" printDebug "DEBUG: ls -la $mountPoint" printDebug $( ls -la "$mountPoint" ) unmount