Date created: Friday, April 21, 2017 12:28:04 PM. Last modified: Sunday, January 27, 2019 11:46:00 AM
Rsync Backup Window
From 23.00 onwards (when the cronjob is scheduled to start) up until 07.30 the following morning, run rsync in a continuous loop. This is incase the connection is dropped overnight, then the backup jobs will fall behind. Whilst rsync is running the script checks the time, if it reaches 07.30 the script will kill rsync and exit (this is the end of the backup window). FINISH_DAYS is an offset from the start day, starting at 23.00 and one night and finishing at 07.30 the next day, the FINISH_DAYS offset is 1, use 0 for the same day, +2 to run all weekend etc.
#!/bin/bash
set -u
# Both with leading zero
# 00-23:
FINISH_HOUR=07
# 00-59:
FINISH_MINUTE=00
# Additional days, no leading zero
FINISH_DAY=1
# Nothing to edit below here...
declare -a RSYNC_CMD
RSYNC_CMD[0]="/usr/bin/rsync -vrhit --partial --progress --stats --delete -e \"ssh -p 12345\" /media/drive1/dir1/ backup-user@1.2.3.4:~/backup/dir1/ &"
RSYNC_CMD[1]="/usr/bin/rsync -vrhit --partial --progress --stats --delete -e \"ssh -p 12345\" /media/drive2/dir2/ backup-user@1.2.3.4:~/backup/dir2/ &"
RSYNC_CMD[2]="/usr/bin/rsync -vrhit --partial --progress --stats --delete -e \"ssh -p 12345\" /media/drive3/dir3/ backup-user@1.2.3.4:~/backup/dir3/ &"
RSYNC_COUNT=2
INDEX=0
RSYNC_PID=0
function watch_rsync() {
while true
do
# If the backup window has ended, kill rsync and exit
NOW=$(date +"%s")
if [[ $NOW -ge $2 ]]
then
echo "Killing PID $RSYNC_PID at: `date`"
kill $RSYNC_PID
exit 1
fi
sleep 60
done
}
echo "Starting at: `date`"
END_DATE=$(date -d "+$FINISH_DAY day $FINISH_HOUR:$FINISH_MINUTE:00" +"%s")
echo "End date is: `date -d @$END_DATE`"
while true
do
eval ${RSYNC_CMD[$INDEX]}
RSYNC_PID=$!
watch_rsync $RSYNC_PID $END_DATE &
wait $RSYNC_PID
RET=$?
# If the current rsync command completed successfully,
# move on to the next rsync task
if [[ $RET -eq 0 ]]
then
let INDEX=INDEX+1
if [[ $INDEX -gt $RSYNC_COUNT ]]
then
# All rsync jobs have finished so exit
echo "Finishing at: `date`"
exit 0
fi
# Exit code 20 means rsync received SIGUSR1 or SIGINT
elif [[ $RET -eq 20 ]]
then
# Rsync was killed so stop the script
echo "Stopping at: `date`"
exit 1
fi
# Else if it wasn't exit code 0 or 20, rsync was probably
# interrupted by a connection drop for example, so loop
# back around and start the same rsync job again.
done
Previous page: Monthly Rsync Backup Example
Next page: Rsync with Notification