#!/usr/bin/env bash ############# # Variables # ############# # Define formatting variables fb="$(tput bold)" ; readonly fb fr="$(tput sgr0)" ; readonly fr # Set sync primary location syn_prime="" ; readonly syn_prime # Set sync secondary location syn_sec="" ; readonly syn_sec # Create required variables array required_vars=( 'syn_prime' 'syn_sec' ) ; readonly required_vars ############# # Functions # ############# display_usage() { local help_msg # Define local variable help_msg="Usage: '${0}' Purpose: Sync removable media drive. Variables to set: syn_prime Primary sync directory. syn_sec Secondary sync directory." echo "${help_msg}" } # Verify object exists and is a directory val_extant_dir() { local to_test to_test="${1}" [[ -d "${to_test}" ]] ; echo "${?}" } # Parse arguments parse_args() { local parsed_args inv_ents parsed_args="$(getopt \ -n "${0##*/}" \ -o h \ --long help \ -- "${@}")" # Check for invalid entries inv_ents="${?}" ; readonly inv_ents if [[ "${inv_ents}" -ne 0 ]]; then echo '' display_usage exit 1 fi # Set positional parameters using parsed argument string eval set -- "${parsed_args}" # Evaluate options while true; do case "${1}" in '-h' | '--help') display_usage exit 0 ;; '--') ## End of options shift break ;; esac done } # Run initialization checks run_init_cks() { local err_msg unset_vars required_var # Create unset variables array declare -a unset_vars # Verify that required variables are set for required_var in "${required_vars[@]}"; do if ! [[ "${!required_var}" ]]; then unset_vars+=("${required_var}") fi done # Exit script if variables are not set if [[ "${unset_vars[*]}" ]]; then err_msg='\nSet the following variable(s) before ' err_msg+='running the script again:' echo -e "${err_msg}\n${fb}${unset_vars[*]}${fr}" 1>&2 exit 1 fi } # Define starting point for execution of the program main() { parse_args "${@}" run_init_cks # Verify primary and secondary drive directories are present pass_or_fail_src="$(val_extant_dir "${syn_prime}")" pass_or_fail_des="$(val_extant_dir "${syn_sec}")" if [[ "${pass_or_fail_src}" -eq 0 && "${pass_or_fail_des}" -eq 0 ]]; then while true; do # Prompt for input, save to variable read -p 'Sync to (t) or from (f) secondary drive? ' -r syn_choice # Check for valid selection if [[ "${syn_choice}" == 't' || "${syn_choice}" == 'f' ]]; then break elif [[ "${syn_choice}" == 'q' ]]; then exit 0 else err_msg='\nInvalid input. Try again or enter q to quit.' echo -e "${err_msg}" 1>&2 fi done if [[ "${syn_choice}" == 't' ]]; then rsync \ -aHAXx \ --delete \ --filter='-x security.selinux' \ --info=progress2 \ --inplace \ --numeric-ids \ "${syn_prime}/" "${syn_sec}/" elif [[ "${syn_choice}" == 'f' ]]; then rsync \ -aHAXx \ --delete \ --filter='-x security.selinux' \ --info=progress2 \ --inplace \ --numeric-ids \ "${syn_sec}/" "${syn_prime}/" fi else err_msg='\nCheck that primary/secondary drive directories ' err_msg+='are available.' echo -e "${err_msg}" 1>&2 exit 1 fi } ########### # Program # ########### main "${@}" # Start program exit 0 # Exit script with successful exit status