Simple rsync based backup script

This simple bash script is able to backup all given files and folders to a backup destination. I use it to backup all my Raspberry Pis, Banana Pis and also my notebook to my Synology NAS.

#!/bin/bash
set -e

# Lockfilecheck for race condition protection 
PIDFILE=/tmp/shared.lock
(
    if ! flock -n 9 ; then
        echo "Another instance is already running dude!";
        exit 1;
    fi
    
    #echo "1: $1";
    #echo "2: $2";
    #echo "3: $3";
    #echo "4: $4";
    
    DATE=`date +%y%m%d`;
    
    SOURCES="/*";
    
    if [ "$1" == "help" ]
        then
        echo "Help";
        echo "- USAGE: bash rsync_backup.sh [DIRTOBACKUP] [EXCLUDEFILEPATH] [BACKUPDESTINATION] [disable-dry-run]";
        echo "- OR: bash rsync_backup.sh null null [BACKUPDESTINATION] [disable-dry-run]";
        echo "- OR: bash rsync_backup.sh [DIRTOBACKUP] null [BACKUPDESTINATION] [disable-dry-run]";
        echo "- OR: bash rsync_backup.sh [DIRTOBACKUP] null [BACKUPDESTINATION] [disable-dry-run] [logfile]";
        exit 0;
    elif [ -n "$1" -a "$1" != "null" ]
        then 
        SOURCES="$1";
    fi 
    
    EXCLUDEFILE="";
    if [ -n "$2" -a "$2" != "null" ]
        then
        EXCLUDEFILE="--exclude-from=$2";
    fi
    
    # Define remote target
    TARGET="";
    if [ -n "$3" -a "$3" != "null" ] 
        then
        TARGET="$3";
    else
        echo "You have to give me a destination";
        exit 1;     
    fi
    
    DRYRUN="--dry-run";
    if [ -n "$4" -a "$4" == "disable-dry-run" ]
        then
        DRYRUN="";
    fi
    # rsync base params
    # --delete - delete destination files that dosn't exist on the source
    # --exclude-from - file / folders to ignore can be 
    #
    # use -–dry-run to simulate backup -> this is the default mode unless disable-dry-run is set
    PARAMS="-hazv --delete --info=progress2 --progress --stats";
    
    # Path to logfile
    LOGFILE="rsync_log.$DATE.log";
    if [ -n "$5" -a "$5" != "null" ]
        then
        LOGFILE="$5";
    fi

    # determine the path to "rsync"
    RSYNC=`which rsync`;
    
    # run backup command
    echo "run: $RSYNC $PARAMS $DRYRUN $EXCLUDEFILE $SOURCES $TARGET > $LOGFILE;"
    $RSYNC $PARAMS $DRYRUN $EXCLUDEFILE $SOURCES $TARGET > $LOGFILE;
    
    exit 0;
) 9> "$PIDFILE"

Example call:

$> rsync_backup.sh "/data/snots/*" exclude.txt backup@ds.intern.ask-sheldon.com:/volume1/NetBackup/thinkpad disable-dry-run logfile.log

If you want to run it as a crontab, you can use key based authentication (see SSH key authentication).

The script is also able to ignore defined source paths based on a exclude list. On Ubuntu for example the following  files and folders have to be excluded in a backup to be able to boot from the backup in a case of disaster recovery. That’s why they are listed in the exclude.txt:

/dev/* 
/home/*/.gvfs 
/home/*/.mozilla/firefox/*/Cache 
/home/*/.cache/chromium 
/home/*/.thumbnails 
/media/* 
/mnt/* 
/proc/* 
/sys/* 
/tmp/* 
/home/*/.local/share/Trash 
/etc/fstab 
/var/run/* 
/var/lock/* 
/lib/modules/*/volatile/.mounted 
/var/cache/apt/archives/* 
*.Trashes

Permission errors

If you got permission errors like this,

rsync: chown "/mnt/all-inkl/." failed: Permission denied (13)
rsync: failed to set times on "/mnt/all-inkl/etc/alternatives/vim": No such file or directory (2)

You probably don’t have the the rights to change the users or permissions on the target host. The errors occurs because rsync tries to assign the same users, groups, timestamps and permissions to the files and folders on the target system as they are set on the source system.

The solution is, to change the rsync-parameters like that:

PARAMS="-azvu --no-o --no-g --no-t --delete";

Leave a Reply

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

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.