Skip to content

Instantly share code, notes, and snippets.

@polprog
Last active December 8, 2017 10:40
Show Gist options
  • Save polprog/47e6a92900d8280ee8415ef08023e246 to your computer and use it in GitHub Desktop.
Save polprog/47e6a92900d8280ee8415ef08023e246 to your computer and use it in GitHub Desktop.
Simple rsync based incremental and snapshot backup script
This was created as a helper script for backing up my directory with VMs
It's not the prettiest one, but it's very simple and flexible. Works for me!
Be careful with the remove-old option, you may want to back up some of the older back ups to another place,
since it removers EVERY BACKUP OLDER than a week.
You definitely want the backup root to be a separate partition or, even better, separate disk.
It can be put into cron, if you do so I'd suggest a wrapper script like this:
mount -o remount,rw backup_part
* execute backup script *
mount - remount,ro backup_part
TODO:
- option for compressing old backups with tar.
- ass option to override default backup root dir with shell, like this:
$ BACKUP_ROOT=/foo/bar ./backup.sh make baz
Not tested on anything else than my VM server (debian 9.2). Your mileage may vary. CA residents add 5kb bash tax.
Notes:
- If you are on debian 9 you might have to install rsync, if you haven't yet.
- On creating the first backup, rm might complain for no such file or directory. This is normal.
If you repeat the backup again, it should not
- Since my VM server is spun up whenever it needs and I might need to back up often, my timestamp version is very precise.
You may want to change it to something day-precise, or hour-precise: `date +%F-%Hh` or simply `date +%F`
#!/bin/bash
echo "Backup script v0.1"
# The directory where the backups are stored
BACKUP_ROOT='/var/bkp/'
# Dir name for last backup link
LASTONE='lastbkp'
# Timestamp format
TIMESTAMP=`date +%F-%T`
# Directory to be backed up
SUBJECT=${2%/} # Remove trailing /
case $1 in
"make")
# Create backup directories if they don't exist
if [ ! -d "${BACKUP_ROOT}" ]; then echo "${BACKUP_ROOT} did not exist; creating it"; mkdir ${BACKUP_ROOT}; fi
if [ ! -d "${BACKUP_ROOT}/$LASTONE-$SUBJECT" ]; then echo "${BACKUP_ROOT}/$LASTONE-$SUBJECT did not exist; creating it"; mkdir ${BACKUP_ROOT}/$LASTONE-$SUBJECT; fi
# Synchronize files
rsync -av --progress --link-dest $BACKUP_ROOT/$LASTONE-$SUBJECT "$SUBJECT/" "/${BACKUP_ROOT}/backup-$SUBJECT-$TIMESTAMP"
# Clear out last backup point
rm -r $BACKUP_ROOT/$LASTONE-$SUBJECT/*
# Make transparent structure
cp -al ${BACKUP_ROOT}/backup-$SUBJECT-$TIMESTAMP/* $BACKUP_ROOT/$LASTONE-$SUBJECT
;;
"make-snap")
if [ ! -d "${BACKUP_ROOT}" ]; then echo "${BACKUP_ROOT} did not exist; creating it"; mkdir ${BACKUP_ROOT}; fi
if [ ! -d "${BACKUP_ROOT}/$LASTONE-$SUBJECT" ]; then echo "${BACKUP_ROOT}/$LASTONE-$SUBJECT did not exist; creating it"; mkdir ${BACKUP_ROOT}/$LASTONE-$SUBJECT; fi
# Synchronize files
rsync -av --progress $BACKUP_ROOT/$LASTONE-$SUBJECT "$SUBJECT/" "/${BACKUP_ROOT}/backup-$SUBJECT-$TIMESTAMP"
# Clear out last backup point
rm -r $BACKUP_ROOT/$LASTONE-$SUBJECT/*
# Make transparent structure
cp -al ${BACKUP_ROOT}/backup-$SUBJECT-$TIMESTAMP/* $BACKUP_ROOT/$LASTONE-$SUBJECT
;;
"remove-old")
echo "Removing backups from ${BACKUP_ROOT} older than a week"
#remove older than last week
#find $BACKUP_ROOT -maxdepth 1 -ctime +6 -print
find $BACKUP_ROOT -mindepth 1 -maxdepth 1 -ctime +6 -not -name $LASTONE -exec rm -rv {} \;
#find $BACKUP_ROOT -not -name $LASTONE -mindepth 1 -maxdepth 1 -print
;;
"restore")
# Restore file copies
#cp -rv $BACKUP_ROOT/$LASTONE-$SUBJECT/* $SUBJECT/
rsync -av --progress --delete $BACKUP_ROOT/$LASTONE-$SUBJECT/ $SUBJECT/
;;
"list")
echo "\$BACKUP_ROOT is $BACKUP_ROOT"
echo -e "Available backups:\n"
find $BACKUP_ROOT -name "${LASTONE}*" -print
;;
"help")
echo -e "Usage: $0 <make|make-snap|remove-old|restore> <source directory>"
echo -e " $0 list"
echo -e "\tmake - makes a backup in \$BACKUP_ROOT"
echo -e "\tmake-snap - makes a snapshot backup in \$BACKUP_ROOT"
echo -e "\tremove-old - removes backups which have change time longer than a week ago"
echo -e "\trestore - restores a backup"
echo -e "\tlist - shows last backups"
echo -e "This script should be run in the directory where the source directory is located"
echo -e "since it uses <source-directory> parameter as backup name"
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment