Incrimental Backups: Difference between revisions
From James's Wiki
No edit summary |
No edit summary |
||
Line 3: | Line 3: | ||
<syntaxhighlight lang="Bash"> | <syntaxhighlight lang="Bash"> | ||
#!/bin/bash | #!/bin/bash | ||
#default port if none given | #default port if none given | ||
Latest revision as of 20:36, 29 April 2019
Here is a bash script to do incrimental backups via ssh and rsync.
#!/bin/bash
#default port if none given
getopt --test > /dev/null
if [[ $? -ne 4 ]]; then
echo "I’m sorry, `getopt --test` failed in this environment."
exit 1
fi
OPTIONS=hdwmtvp:rl:
LONGOPTIONS=hourly,daily,weekly,monthly,test,verbose,port:,rsyncskip,login:
# -temporarily store output to be able to check for errors
# -e.g. use “--options” parameter by name to activate quoting/enhanced mode
# -pass arguments only via -- "$@" to separate them correctly
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTIONS --name "$0" -- "$@")
if [[ $? -ne 0 ]]; then
# e.g. $? == 1
# then getopt has complained about wrong arguments to stdout
echo "This is an incrimental backup system designed to make backups from remote systems to the local system"
echo "You can also make backups from the local system to the local system"
echo "This script is designed to be run as a cronjob and normally will provide no output"
echo "Since this script is run as a cronjob and uses ssh to connect to remote servers, you must use ssh-keys to avoid password prompts"
echo
echo "USAGE: ./testscript [options] <source> <destination>"
echo "The options are:"
echo "-h or --hourly for preforming hourly incrimental backups"
echo "-d or --daily for preforming daily incrimental backups"
echo "-w or --weekly for preforming weekly incrimental backups"
echo "-m or --monthly for preforming monthly incrimental backups"
echo "-t or --test for test mode. The program will run through the process of prefroming a backup without actually makeing any real changes"
echo "-v or --verbose adds output for testing purposes"
echo "-l or --login <someuser@1.2.3.4> used to specify your username and the ip address of the remote server"
echo "-p or --port <1234> used to specify the remote servers port to connect to. The default is 22"
echo "-r or rsyncskip used to skip the rsync dry-run command if your trying to see whats going on with -v or --verbose and rsync is filling up your scroll buffer"
exit 2
fi
# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"
# now enjoy the options in order and nicely split until we see --
while true; do
case "$1" in
-h|--hourly)
MODE=HOURLY
shift
;;
-d|--daily)
MODE=DAILY
shift
;;
-w|--weekly)
MODE=WEEKLY
shift
;;
-m|--monthly)
MODE=MONTHLY
shift
;;
-t|--test)
TESTRUN=YES
shift
;;
-v|--verbose)
VERBOSE=YES
shift
;;
-p|--port)
PORT="-p $2";
shift 2;;
-l|--login)
LOGIN="$2";
shift 2;;
-r|--rsyncskip)
RSYNCSKIP=YES
shift;;
-H|--help)
echo "This is an incrimental backup system designed to make backups from remote systems to the local system"
echo "You can also make backups from the local system to the local system"
echo "This script is designed to be run as a cronjob and normally will provide no output"
echo "Since this script is run as a cronjob and uses ssh to connect to remote servers, you must use ssh-keys to avoid password prompts"
echo
echo "USAGE: ./testscript [options] <source> <destination>"
echo "The options are:"
echo "-h or --hourly for preforming hourly incrimental backups"
echo "-d or --daily for preforming daily incrimental backups"
echo "-w or --weekly for preforming weekly incrimental backups"
echo "-m or --monthly for preforming monthly incrimental backups"
echo "-t or --test for test mode. The program will run through the process of prefroming a backup without actually makeing any real changes"
echo "-v or --verbose adds output for testing purposes"
echo "-l or --login <someuser@1.2.3.4> used to specify your username and the ip address of the remote server"
echo "-p or --port <1234> used to specify the remote servers port to connect to. The default is 22"
echo "-r or rsyncskip used to skip the rsync dry-run command if your trying to see whats going on with -v or --verbose and rsync is filling up your scroll buffer"
echo
exit 0;
;;
--)
shift
break
;;
*)
echo "Programming error"
exit 3
;;
esac
done
# handle non-option arguments
if [[ $# -ne 2 ]]; then
echo "$0: A single input file is required."
exit 4
fi
# test to make sure the source exists and is reachable
if [ -n "$LOGIN" ]; then
if ! ssh "$PORT" "$LOGIN" ls "$1" >/dev/null 2>&1 ; then
echo "ERROR Target Directory: $2 is unreachable or does not exist"
exit 1;
else
SOURCE="$LOGIN:$1"
fi
else
SOURCE="$1"
fi
#check to see if the destination dir exists
if [ -d "$2" ]; then
TRG="$2"
else
echo "destination directory doesn't exist."
exit 1;
fi
# Perform an hourly backup
if [ $MODE = HOURLY ]; then
#Today's date:
DAY0=`date +%Y_%a_%b_%d_%H`
#Today's date minus 25 hours
DAY24=`date -d "25 hours ago" +%Y_%a_%b_%d_%H`
#One hour ago:
DAY1=`date -d "1 hour ago" +%Y_%a_%b_%d_%H`
#The target directory:
TRG+=$DAY0
#The Link Dir
LNKDIR="/media/4USB/backup/sserver/$DAY1/"
if [ -d "$LNKDIR" ]; then
LNK="--link-dest=$LNKDIR"
else
LNK=""
fi
#Set rsync run options
if [[ $TESTRUN = YES ]]; then
if [[ $VERBOSE = YES ]]; then
#Verbose + Test Mode
OPT="-ahvn --delete"
echo "Hourly Mode: Verbose + Test Mode"
echo
else
#Quite + Test Mode
OPT="-ahqn --delete"
fi
else
if [[ $VERBOSE = YES ]]; then
#Verbose + Real Run
OPT="-ahv --delete"
echo "Hourly Mode: Verbose + Real Run"
echo
else
#Quiet + Real Run
OPT="-ahq --delete"
fi
fi
if [[ $VERBOSE = YES ]]; then
echo "This script will backup files from:"
echo "$SOURCE"
echo
echo "To:"
echo "$TRG"
echo
if [ -d "$LNKDIR" ]; then
echo "The files in: $SOURCE that match the files in"
echo "$LNKDIR will be symbolicly linked instead of copied"
else
echo "This must be the first time a backup of this type has"
echo "been made because the link directory: $LNKDIR does not exist"
fi
echo
echo "The rsync command that will be used is:"
echo "rsync "$OPT $LNK -e "'ssh -p 2222'" $SRC $TRG
echo
fi
#Execute the backup
if [[ $RSYNCSKIP != "YES" ]]; then
rsync $OPT $LNK -e 'ssh -p 2222' $SOURCE $TRG
fi
#Delete the backup from 25 hours ago, if it exists
if [[ $VERBOSE = YES ]]; then
if [ -d /media/4USB/backup/sserver/$DAY24 ]; then
echo "Old backup found."
echo
if [[ $TESTRUN = YES ]]; then
echo "simulatingdeleting old backup:"
echo "rm -Rf /media/4USB/backup/sserver/$DAY24"
fi
else
echo "Old backup from 25 hours ago NOT found"
echo
fi
else
if [ -d /media/4USB/backup/sserver/$DAY24 ]; then
if [[ $TESTRUN != YES ]]; then
rm -Rf /media/4USB/backup/sserver/$DAY24
fi
fi
fi
elif [ $MODE = DAILY ]; then
#Today's date:
DATE_TODAY=`date +%Y_%a_%b_%d`
#The date at last midnight******maybe check and see if it exists if not then error out*****
DATE_LAST_MIDNIGHT=`date -d "1 day ago" +%Y_%a_%b_%d_00`
#DATE_8_DAYS_AGO
DATE_8_DAYS_AGO=`date -d "8 days ago" +%Y_%a_%b_%d`
#The target directory:
TRG+=$DAY0
#The Link Dir
LNKDIR="/media/4USB/backup/sserver/$DATE_LAST_MIDNIGHT/"
if [ -d "$LNKDIR" ]; then
LNK="--link-dest=$LNKDIR"
else
LNK=""
fi
#Set rsync run options
if [[ $TESTRUN = YES ]]; then
if [[ $VERBOSE = YES ]]; then
#Verbose + Test Mode
OPT="-ahvn --delete"
echo "Daily Mode: Verbose + Test Mode"
echo
else
#Quite + Test Mode
OPT="-ahqn --delete"
fi
else
if [[ $VERBOSE = YES ]]; then
#Verbose + Real Run
OPT="-ahv --delete"
echo "Daily Mode: Verbose + Real Run"
echo
else
#Quiet + Real Run
OPT="-ahq --delete"
fi
fi
if [[ $VERBOSE = YES ]]; then
echo "This script will backup files from:"
echo "$SOURCE"
echo
echo "To:"
echo "$TRG"
echo
if [ -d "$LNKDIR" ]; then
echo "The files in: $SOURCE that match the files in"
echo "$LNKDIR will be symbolicly linked instead of copied"
else
echo "This must be the first time a backup of this type has"
echo "been made because the link directory: $LNKDIR does not exist"
fi
echo
echo "The rsync command that will be used is:"
echo "rsync "$OPT $LNK -e "'ssh -p 2222'" $SRC $TRG
echo
fi
#Execute the backup
if [[ $RSYNCSKIP != "YES" ]]; then
rsync $OPT $LNK -e 'ssh -p 2222' $SOURCE $TRG
fi
#Delete the backup from 8 days ago, if it exists
if [[ $VERBOSE = YES ]]; then
if [ -d /media/4USB/backup/sserver/$DATE_8_DAYS_AGO ]; then
echo "Old backup found."
echo
if [[ $TESTRUN = YES ]]; then
echo "simulatingdeleting old backup:"
echo "rm -Rf /media/4USB/backup/sserver/$DATE_8_DAYS_AGO"
fi
else
echo "Old backup from 8 days ago NOT found"
echo
fi
else
if [ -d /media/4USB/backup/sserver/$DATE_8_DAYS_AGO ]; then
if [[ $TESTRUN != YES ]]; then
rm -Rf /media/4USB/backup/sserver/$DATE_8_DAYS_AGO
fi
fi
fi
#Weekly backup. Saves 4 weeks worth of backups.
elif [ $MODE = WEEKLY ]; then
#Today's week number:
DATE_THIS_WEEK=`date +%Y_Week_%U`
#Today's date:
DATE_TODAY=`date +%Y_%a_%b_%d`
#Date one week ago
DATE_5_WEEKS_AGO=`date -d "5 weeks ago" +%Y_Week_%U`
#The target directory:
TRG+=$DAY0
#The Link Dir
LNKDIR="/media/4USB/backup/sserver/$DATE_5_WEEKS_AGO/"
#Check and see if the link directory exists. if not then don't use the rsync --link-dest option
if [ -d "$LNKDIR" ]; then
LNK="--link-dest=$LNKDIR"
else
LNK=""
fi
#Set rsync run options
if [[ $TESTRUN = YES ]]; then
if [[ $VERBOSE = YES ]]; then
#Verbose + Test Mode
OPT="-ahvn --delete"
echo "Weekly Mode: Verbose + Test Mode"
echo
else
#Quite + Test Mode
OPT="-ahqn --delete"
fi
else
if [[ $VERBOSE = YES ]]; then
#Verbose + Real Run
OPT="-ahv --delete"
echo "Weekly Mode: Verbose + Real Run"
echo
else
#Quiet + Real Run
OPT="-ahq --delete"
fi
fi
if [[ $VERBOSE = YES ]]; then
echo "This script will backup files from:"
echo "$SOURCE"
echo
echo "To:"
echo "$TRG"
echo
if [ -d "$LNKDIR" ]; then
echo "The files in: $SOURCE that match the files in"
echo "$LNKDIR will be symbolicly linked instead of copied"
else
echo "This must be the first time a backup of this type has"
echo "been made because the link directory: $LNKDIR does not exist"
fi
echo
echo "The rsync command that will be used is:"
echo "rsync "$OPT $LNK -e "'ssh -p 2222'" $SRC $TRG
echo
fi
#Execute the backup
if [[ $RSYNCSKIP != "YES" ]]; then
rsync $OPT $LNK -e 'ssh -p 2222' $SOURCE $TRG
fi
#Delete the backup from 5 weeks ago, if it exists
if [[ $VERBOSE = YES ]]; then
if [ -d /media/4USB/backup/sserver/$DATE_5_WEEKS_AGO ]; then
echo "Old backup found."
echo
if [[ $TESTRUN = YES ]]; then
echo "simulatingdeleting old backup:"
echo "rm -Rf /media/4USB/backup/sserver/$DATE_5_WEEKS_AGO"
fi
else
echo "The Old backup from 5 weeks ago was NOT found"
echo
fi
else
if [ -d /media/4USB/backup/sserver/$DATE_5_WEEKS_AGO ]; then
if [[ $TESTRUN != YES ]]; then
rm -Rf /media/4USB/backup/sserver/$DATE_5_WEEKS_AGO
fi
fi
fi
#Monthly backup. Saves 12 months worth of backups.
elif [ $MODE = MONTHLY ]; then
#Today's week number:
DATE_THIS_MONTH=`date +%Y_%m`
#Today's date:
DATE_TODAY=`date +%Y_%a_%b_%d`
#Date one week ago
DATE_13_MONTHS_AGO=`date -d "13 months ago" +%Y_%m`
#The target directory:
TRG+=$DAY0
#The Link Dir
LNKDIR="/media/4USB/backup/sserver/$DATE_13_MONTHS_AGO/"
#Check and see if the link directory exists. if not then don't use the rsync --link-dest option
if [ -d "$LNKDIR" ]; then
LNK="--link-dest=$LNKDIR"
else
LNK=""
fi
#Set rsync run options
if [[ $TESTRUN = YES ]]; then
if [[ $VERBOSE = YES ]]; then
#Verbose + Test Mode
OPT="-ahvn --delete"
echo "Monthly Mode: Verbose + Test Mode"
echo
else
#Quite + Test Mode
OPT="-ahqn --delete"
fi
else
if [[ $VERBOSE = YES ]]; then
#Verbose + Real Run
OPT="-ahv --delete"
echo "Monthly Mode: Verbose + Real Run"
echo
else
#Quiet + Real Run
OPT="-ahq --delete"
fi
fi
if [[ $VERBOSE = YES ]]; then
echo "This script will backup files from:"
echo "$SOURCE"
echo
echo "To:"
echo "$TRG"
echo
if [ -d "$LNKDIR" ]; then
echo "The files in: $SOURCE that match the files in"
echo "$LNKDIR will be symbolicly linked instead of copied"
else
echo "This must be the first time a backup of this type has"
echo "been made because the link directory: $LNKDIR does not exist"
fi
echo
echo "The rsync command that will be used is:"
echo "rsync "$OPT $LNK -e "'ssh -p 2222'" $SRC $TRG
echo
fi
#Execute the backup
if [[ $RSYNCSKIP != "YES" ]]; then
rsync $OPT $LNK -e 'ssh -p 2222' $SOURCE $TRG
fi
#Delete the backup from 13 months ago, if it exists
if [[ $VERBOSE = YES ]]; then
if [ -d /media/4USB/backup/sserver/$DATE_13_MONTHS_AGO ]; then
echo "Old backup found."
echo
if [[ $TESTRUN = YES ]]; then
echo "simulatingdeleting old backup:"
echo "rm -Rf /media/4USB/backup/sserver/$DATE_5_WEEKS_AGO"
fi
else
echo "The Old backup from 13 months ago was NOT found"
echo
fi
else
if [ -d /media/4USB/backup/sserver/$DATE_13_MONTHS_AGO ]; then
if [[ $TESTRUN != YES ]]; then
rm -Rf /media/4USB/backup/sserver/$DATE_13_MONTHS_AGO
fi
fi
fi
fi