#!/bin/bash function join { local d=$1; shift; local p=$1; shift; echo -n "$p$1"; shift; printf "%s" "${@/#/$d$p}"; } if ! lockfile-create -p -r 2 $0; then echo "Another backup is running, aborting" exit 49 fi ### Program arguments ### # Backup target directory BACKUP_TARGET=$1 # Backup local directory BACKUP_DIRECTORY=$2 # Exclusions BACKUP_EXCLUSIONS=$(join " " "--exclude=" $3) echo "Exclusions: $BACKUP_EXCLUSIONS" # Script executed before starting the backup BEFORE_SCRIPT=$4 # Script executed after finishing the backup AFTER_SCRIPT=$5 # Backup root path, change it to create a new backup BACKUP_ROOT=$6 # Backup archive path, change it for each backup BACKUP_ARCHIVE=$7 # Backup additional arguments BACKUP_ARGS=$8 ### Backup automatic properties ### BACKUP_ROOT_PATH="$(cat /etc/hostname)" BACKUP_BASE_PATH="$BACKUP_ROOT_PATH/$BACKUP_ROOT" BACKUP_CONTENTS_PATH="$BACKUP_BASE_PATH/_backup/" RSYNC_BASE_CMD=(rsync --timeout=120 -avzzhP) RSYNC_BASE_CMD+=("$BACKUP_ARGS") RSYNC_STRUCTURE_CMD=${RSYNC_BASE_CMD[*]} RSYNC_STRUCTURE_CMD+=(--relative $BACKUP_CONTENTS_PATH $BACKUP_TARGET) RSYNC_DATA_CMD=${RSYNC_BASE_CMD[*]} RSYNC_DATA_CMD+=(--delete --inplace $BACKUP_EXCLUSIONS) if [ ! -z "$BACKUP_ARCHIVE" ]; then RSYNC_DATA_CMD+=(--backup --backup-dir=../$BACKUP_ARCHIVE) fi RSYNC_DATA_CMD+=($BACKUP_DIRECTORY $BACKUP_TARGET/$BACKUP_CONTENTS_PATH) echo "Starting backup. Target: $BACKUP_BASE_PATH. Archive: $BACKUP_ARCHIVE" ### Before Script ### echo "Before script ..." eval "$BEFORE_SCRIPT" echo "Done" ### Create local model of the remote's backup directory tree and send it ### echo "Directory structure..." cd ~/ mkdir -p "$BACKUP_CONTENTS_PATH" eval ${RSYNC_STRUCTURE_CMD[*]} || exit 1 echo "Done" ### Backup home directory except some unwanted files ### echo "Backup data..." eval ${RSYNC_DATA_CMD[*]} || exit 1 echo "Done" ### Remove local model of the backup directory tree ### rm -R "$BACKUP_ROOT_PATH" ### After Script ### eval "$AFTER_SCRIPT" # Remove lock echo "Backup finished. Removing lock..." lockfile-remove $0