====== 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"