Rdiff-Backup Wrapper Script

I use rdiff-backup on all my servers and desktop machines, including routers, laptops, etc. to make sure all data and configuration files are safe. To this end, especially for Linux/unix hosts, I’ve created a Bash script which takes care of process locking and excluding files which shouldn’t go into the archive. In hopes it’ll be useful to someone, you can download it, or view it:

#!/bin/bash
#
VERSION=0.11
# 2011/09/05
#
# Please do not put spaces in the name of this script,
# the lock file is based on $0 and spaces break things.
#
# You will want something like this in ~/.ssh/config, where the virtual host
# name corresponds to the REMOTEHOST variable below:
#
# Host my-backup
# 	Hostname backupserver.my.lan
# 	User backup
# 	Identityfile /root/.ssh/id_rsa_my_backup
# 	Compression yes
# 	Protocol 2
#
#
#
# Changelog:
#
# 2011/09/05 - Aaron Ten Clay <[email protected]>
#              Corrected output redirection and added filtering for harmless error messages
#
# 2011/04/10 - Aaron Ten Clay <[email protected]>
#              Updated order of include/exclude arguments to capture kernel config
#              Added output filtering via Grep to ignore SpecialFileError messages
#
# 2009/07/20 - Aaron Ten Clay <[email protected]>
#              Added rudimentary version checking
#
# 2009/02/21 - Aaron Ten Clay <[email protected]>
#              Fixed spelling error
#
# 2009/01/20 - Aaron Ten Clay <[email protected]>
#              Repaired grammar in error messages
#
# 2009/01/17 - Aaron Ten Clay <[email protected]>
#              Repaired remote version error message
#


# Quick customization parameters
HOSTNAME="your.host.name"
LOCALVERSION=$(rdiff-backup --version)
REMOTEPATH="/backups/${HOSTNAME}/root"
REMOTEHOST="my-backup"


# Main script

function check_script_version {
	latest=$(wget --no-check-certificate -qO- "https://www.aarontc.com/projects/rdiff-backup-wrapper-script/version_check.php?version=${VERSION}")
	if [[ "x${latest}" == "x" ]]; then
		echo "Notice: Version check failed"
	else
		if [[ "${latest}" != "latest" ]]; then
			echo -e "Notice: A newer version (${latest}) of this script is available at http://www.aarontc.com/projects/rdiff-backup-wrapper-script\n"
		fi
	fi
}

function sigcaught () {
	rm -f "$lockfile"
	echo "Error: caught interrupt" >&2
	exit 2
}



# Here begins the actual work

# Exit if using uninitialized variable
set -o nounset

check_script_version

remoteversion=$(ssh ${REMOTEHOST} rdiff-backup --version)

if [[ "${LOCALVERSION}" != "${remoteversion}" ]]; then
	echo "Error: Remote version (${remoteversion}) differs from local version (${LOCALVERSION}), aborting" >&2
	exit 1
fi

lockfile="/tmp/$(basename $0).pid"

if ( set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; then
	trap sigcaught INT TERM EXIT

	rdiff-backup \
		--exclude /home/shares \
		--exclude /dev \
		--exclude /media \
		--exclude /mnt \
		--exclude /opt \
		--exclude /proc \
		--exclude /sys \
		--exclude /tmp \
		--exclude /usr/portage \
		--exclude /usr/tmp \
		--include /usr/src/linux/.config \
		--exclude /usr/src \
		--exclude /var/cache \
		--exclude /var/log \
		--exclude /var/tmp \
		--exclude /var/lib/vmware \
		--exclude /var/lib/gentoo \
		$* \
		"/" \
		"${REMOTEHOST}::${REMOTEPATH}" \
		2>&1 \
		| grep -v "^SpecialFileError .* Socket error: AF_UNIX path too long$" \
		| grep -v "^UpdateError .* Updated mirror temp file .* does not match source$" \
		| grep -v "^ListError .* No such file or directory: .*$"


	rm -f "$lockfile"
	trap - INT TERM EXIT
else
	echo "Error: Failed to acquire lockfile: $lockfile, held by PID $(cat $lockfile)" >&2
fi