====== Full system rsync ======
This script will perform a full system backup with rsync, leaving out /dev and /tmp and what not.
There are several configuration parameters:
* ''target'' : system to back up, must be set to output of ''uname -n''. Used as a sanity check.
* ''source_dir'' : source directory. Set to ''/'' for full system backup.
* ''target_dir'' : target directory. Set to the mountpoint of an external hard drive or a remote server. Note: make sure that ''target_dir'' or a parent is included in ''exclude_dir'' otherwise rsync will recurse and your hard drive will get filled up completely.
* ''exclude_dir'' : excluded directories. Set these to temporary directories and other things you don't want backed up.
* ''include_dir'' : included directories. Subfolders of excluded directories to include.
If you want to use this script with a remote host where the target user is not root, change flags to
flags=(-avPse ssh --delete --ignore-errors --rsync-path="rsync --fake-super")
and use a remote path of the form ''user@host:path'' for ''target_dir''
====== backup-system ======
#!/bin/bash
set -f
hostname=$(hostname -s)
target="my-hostname"
source_dir="/"
target_dir="/media/external-hard-drive/$target/"
exclude_dir=(*/.gvfs /media /run/media /sys /dev /proc /mnt /tmp pagefile.sys hiberfil.sys /home/*/.cache .mozilla/firefox/*/Cache .Trash-1000)
include_dir=(/mnt/linux-data/opt /mnt/data)
flags=(-avPAX --delete --ignore-errors)
if [ -n "$target" ] ; then
if [ "$hostname" != "$target" ] ; then
echo Error: must be run on $target
exit 1
fi
fi
include=()
# process include directories
for d in "${include_dir[@]}"
do
found=0
dir=""
shortest_parent="/"
echo include_dir $d
# Need to deal with rsync idiosyncracies
# by including excluded directories
# but not their contents
# Removes matches to the include directory
# and finds the shortest parent path
for d2 in "${exclude_dir[@]}"
do
echo exclude_dir $d2
if [[ $d = $d2* ]]; then
found=1
if [[ "$shortest_parent" == "/" ]]; then
shortest_parent=$d2
else
if [ ${#shortest_parent} -gt ${#d2} ]; then
shortest_parent=$d2
fi
fi
fi
echo shortest_parent $shortest_parent
done
if [[ $found ]]; then
path=$(dirname "$d")
while [[ "$path" != "/" ]]; do
exclude_dir+=("$path/*")
include+=("--include=$path")
if [[ "$path" == "$shortest_parent" ]]; then
break
fi
path=$(dirname "$path")
done
fi
include+=("--include=$d")
done
exclude=()
for d in "${exclude_dir[@]}"
do
exclude+=("--exclude=$d")
done
sudo -E rsync "${flags[@]}" "${include[@]}" "${exclude[@]}" "$source_dir" "$target_dir"