#!/bin/bash # shellcheck disable=SC2001 # See if you can use ${variable//search/replace} instead. # It is more easy with sed to remove multiple trailing / sq_toolBin=rsync sq_aptOpt= sq_config=0 seq_config() { if initSeqConfig -t "${seq_configName:?}" "${seq_configTemplate:?}" ; then sq_config=1 else error -e "Check output for errors" # End if no configuration file exists dry || return 1 fi interactive || sq_aptOpt="-y" return 0 } step_1_info() { echo "Backup root" echoinfo "Essential excludes are provided in the configuration template." echoinfo "(${seq_configTemplate})" } step_1_options() { echo "[ADDITIONAL_EXCLUDES...]"; } step_1_alias() { echo "buroot"; } step_1() { local buTarget="/backup" if (( ! sq_config )) ; then error -e "Cannot backup root without properly configured excludes" error -e " (expected config: ${seq_configFile:?})" else buTarget="$BACKUP_TARGET" fi # don't use step number shift step budir / "$buTarget" "${BACKUP_EXCLUDES[@]}" "$@" } step_3_info() { # Backup single directory recursively local opt=() local dir='' local tar='[TARGET]' local tarOpt=0 local exc=() shift while [[ "${1:-}" =~ ^- ]] ; do case "${1}" in --) shift && break;; -f) opt+=("${1:-}" "'${2:-}'") shift 2;; -t) tarOpt=1 shift;; -*) opt+=("${1}") shift ;; esac done if [ -n "${1:-}" ] ; then dir="$1" shift if (( tarOpt )) ; then tar="$BACKUP_TARGET" else tar="${1:-}" shift fi for arg in "$@" ; do exc+=("'$arg'") done (( ${#exc[@]} )) || exc=("[NO EXCLUDES]") fi echo "Backup ${opt[*]} '$dir' '$tar' ${exc[*]}" echoinfo " -f : Replace default flags (can be used multiple times)" echoinfo " (default: ${sq_rsyncFlags[*]})" echoinfo " -n : No remount to rw" echoinfo " -t : Using configuration value as TARGET" echoinfo " [EXCLUDES...]" echoinfo "EXCLUDES path notation starts within $dir" echoinfo " e.g. to exclude $dir/a:" echoinfo " $0 budir $dir $tar /a" } sq_rsyncFlags=("-avxHAX" "--delete") step_3_options() { echo "[OPTION] [TARGET] [EXCLUDES...]"; } step_3_alias() { echo "budir"; } step_3() { local configTarget=0 local remount=1 local buSource= local buTarget= local buExcludes= local buLog= local customFlags=() # don't use step number shift for _ in "$@"; do case "$1" in --) shift && break;; -t) configTarget=1 shift;; -n) remount=0 shift;; -f) shift customFlags+=("${1:-}") shift;; esac done (( "${#customFlags[@]}" )) || customFlags=("${sq_rsyncFlags[@]}") if [ -z "${1:-}" ] ; then error -e "Nothing found to backup $1" exit 1 fi buLog="$(basename -- "$1")" if [ "$buLog" == "/" ] ; then buLog="root" buSource="$1" else # remove trailing slashes buSource="$(echo "$1" | sed 's:/*$::')" fi buLog="backup_${buLog}" shift if (( configTarget )) && (( sq_config )) ; then # Taking target from config buTarget="$(echo "$BACKUP_TARGET" | sed 's:/*$::')" else if [ -z "$1" ] ; then error -e "No valid target found" exit 1 fi buTarget="$(echo "$1" | sed 's:/*$::')" shift fi if [ ! -d "${buTarget}" ] && [ ! -L "${buTarget}" ] then error -e "Backup target (${buTarget}) doesn't exist" exit 1 fi for exclu in "$@"; do buExcludes+=("--exclude='$exclu'") done info "Source : $buSource" info "Target : $buTarget" info "Excludes: $*" #fix doubling trailing slash on verbose output when backing up root local tmpSource="$buSource/" local tmpTarget= tmpTarget="${buTarget}/$(basename -- "${buSource}")" if [ "$buSource" == "/" ] ; then tmpSource="/" tmpTarget="${buTarget}/" fi if (( remount )) ; then # remount target to be writable exep "mount -o rw,remount '${buTarget}' >>/dev/null 2>&1" endReturn "Remount (${buTarget}) to be writable failed" fi if [ ! -w "${buTarget}" ] ; then error -e "Backup target (${buTarget}) is not writable" exit 1 fi checkInstalled exep "mv -f '${buTarget}/${buLog}0.log' '/tmp/${buLog}1.log' 2>/dev/null" exep "'${sq_toolBin}' ${customFlags[*]} --info=stats2 ${buExcludes[*]} '${tmpSource}' '${tmpTarget}' > '/tmp/${buLog}0.log'" # mv is not the right tool moving files to a different file system exe cp /tmp/"${buLog}"*.log "${buTarget}" exe rm -rf /tmp/"${buLog}"*.log exe sync if (( remount )) ; then exep "mount -o ro,remount '${buTarget}' >>/dev/null 2>&1" fi } step_100_info() { echo "Install ${sq_toolBin}"; } step_100_alias() { echo "install"; } step_100() { exe apt update exe apt install ${sq_toolBin} ${sq_aptOpt} } checkInstalled() { if ! command -v ${sq_toolBin} >>/dev/null ; then step install fi sq_toolBin="$(command -v ${sq_toolBin})" } # shellcheck disable=SC2034 # Appears unused readonly sqr_minVersion=16 # shellcheck disable=SC1091 # Don't follow this source . /usr/local/bin/sequencer.sh