#!/usr/bin/env mksh # Script by Ypnose - http://ywstd.fr # $ ( cd /mnt && backup -f FILELIST -t $HOME BACKUP ) BACK_DATE="$(date '+%Y-%m-%d')" function p_err { print -u2 -- "$1" exit 1 } function usage { print "usage: backup [-d] [-f FILELIST] [-h] [-t] [SRC] [DEST]" exit } if [[ $1 = "-h" ]]; then usage fi if [[ ! -x $(whence -p rsync) ]]; then p_err "rsync not found in the PATH" fi while getopts ":df:t" opt; do case $opt in d) BACK_DRYR="1" BACK_OPTS+=(--dry-run --log-file=/dev/null) ;; f) BACK_INCL="$OPTARG" ;; t) BACK_SQSH="1" ;; *) usage ;; esac done shift $(( OPTIND - 1 )) # SRC and DEST are required if (( $# < 2 )); then usage fi BACK_DEST="$2" if [[ ! -d $BACK_DEST ]]; then p_err "$BACK_DEST directory is missing" fi if [[ -z $BACK_INCL ]]; then p_err "No include file provided" elif [[ ! -r $BACK_INCL ]]; then p_err "$BACK_INCL is either missing or unreadable" fi # Check rsync(1) man page for pattern rules # With '--files-from', '-r' needs to be specified explicitly rsync \ -ahrvHX \ --checksum \ --delete \ --delete-delay \ --exclude=".gnupg/random_seed" \ --exclude=".gnupg/S.*" \ --exclude="*.dump" \ --exclude="*.qcow2*" \ --exclude="*.raw" \ --exclude="Desktop/" \ --exclude="Downloads/" \ --files-from="$BACK_INCL" \ --log-file="${BACK_DEST}/rsync-${BACK_DATE}.log" \ --numeric-ids \ --stats \ "${BACK_OPTS[@]}" \ "$1" "$BACK_DEST" # Create a Squashfs filesystem only if it's not dry run if (( BACK_SQSH == 1 && BACK_DRYR != 1 )); then sleep 5 mksquashfs \ "$BACK_DEST" \ "BACKUP-$(hostname)-${BACK_DATE}.sqsh" \ -comp gzip \ -keep-as-directory \ -reproducible \ -xattrs fi exit