Linux: Simple incremental backup script

This is a simple script to perform an incremental backup of a directory. It will create a backup folder and in this folder it will create subfolders with a timestamp as name. Every file modified since the last backup will be copied (preserving directories, permissions, owner and timestamp). The first time you execute the script, it will just copy all files.

The root for the backup is defined with an environment variable called BACKUP_ROOT. You can set it with the export command:

export BACKUP_ROOT=/mybackup

If it is not set, /tmp/backup will be used as default (but you can change the default in the script itself).

#!/bin/sh

# Check number of parameters
if [ -z "$1" ]
  then
    echo "Usage: $0 <path_to_dir_to_backup>"
    exit 1
fi

# Check whether directory to backup exists
if [[ ! -d "$1" ]];
  then
    echo "$1 does not exist or is not a directory"
    exit 1
fi

# Use /tmp/backup als default if no backup root is defined
[ -z "$BACKUP_ROOT" ] && BACKUP_ROOT=/tmp/backup

# Create backup root directory if it doesn't exist
[ -d $BACKUP_ROOT ] || mkdir $BACKUP_ROOT

# Move last backup timestamp
[ -f $BACKUP_ROOT/.new_backup ] && mv $BACKUP_ROOT/.new_backup $BACKUP_ROOT/.last_backup

# Create new backup timestamp
touch $BACKUP_ROOT/.new_backup

# Generate a new backup folder name
TIME=$(date '+%Y%m%d%H%M%S')
BACKUP_FOLDER=$BACKUP_ROOT/$TIME

# Create the new backup folder
mkdir $BACKUP_FOLDER

# If there was a previous backup, backup only newer files recreating parent paths and preserving permissions, owner and timestamp
# Or backup all files if it is the first backup
[ -f $BACKUP_ROOT/.last_backup ] && find $1 -type f -newer $BACKUP_ROOT/.last_backup -exec cp -p --parents {} $BACKUP_FOLDER/ \; || find $1 -type f -exec cp -p --parents {} $BACKUP_FOLDER/ \;

I guess there are enough comments in there so that I do not need to go into details about how the script works but feel free to drop a comment in case you have a question.

Leave a Reply

Your email address will not be published. Required fields are marked *