@@ -184,7 +184,7 @@ To run the backup automatically, edit the root crontab.
184184
185185```ini
186186# =================================================================
187- # Configuration for rsync Backup Script v0.25
187+ # Configuration for rsync Backup Script v0.27
188188# =================================================================
189189# !! IMPORTANT !! Set file permissions to 600 (chmod 600 backup.conf)
190190
@@ -301,7 +301,7 @@ END_EXCLUDES
301301
302302` ` ` bash
303303#! /bin/bash
304- # ===================== v0.26 - 2025.08.12 ========================
304+ # ===================== v0.27 - 2025.08.12 ========================
305305#
306306# =================================================================
307307# SCRIPT INITIALIZATION & SETUP
@@ -419,6 +419,14 @@ if [[ -n "${BANDWIDTH_LIMIT_KBPS:-}" && "${BANDWIDTH_LIMIT_KBPS}" -gt 0 ]]; then
419419 RSYNC_BASE_OPTS+=(--bwlimit=" $BANDWIDTH_LIMIT_KBPS " )
420420fi
421421
422+ # Shared options for direct, non-interactive SSH commands
423+ SSH_DIRECT_OPTS=(
424+ -o StrictHostKeyChecking=no
425+ -o BatchMode=yes
426+ -o ConnectTimeout=30
427+ -n
428+ )
429+
422430# =================================================================
423431# HELPER FUNCTIONS
424432# =================================================================
@@ -509,6 +517,8 @@ run_preflight_checks() {
509517 if [[ " $check_failed " == " true" ]]; then exit 10; fi
510518 if [[ " $test_mode " == " true" ]]; then echo " ✅ All required commands are present." ; fi
511519 if [[ " $test_mode " == " true" ]]; then echo " --- Checking SSH connectivity..." ; fi
520+
521+ # Quick preflight connectivity "ping": short 10s timeout for fail-fast behaviour
512522 if ! ssh " ${SSH_OPTS_ARRAY[@]} " -o BatchMode=yes -o ConnectTimeout=10 " $BOX_ADDR " ' exit' 2> /dev/null; then
513523 local err_msg=" Unable to SSH into $BOX_ADDR . Check keys and connectivity."
514524 if [[ " $test_mode " == " true" ]]; then echo " ❌ $err_msg " ; else send_notification " ❌ SSH FAILED: ${HOSTNAME} " " x" " ${NTFY_PRIORITY_FAILURE} " " failure" " $err_msg " ; fi ; exit 6
@@ -581,9 +591,8 @@ run_restore_mode() {
581591 if [[ " $dir_choice " == " $RECYCLE_OPTION " ]]; then
582592 echo " --- Browse Recycle Bin ---"
583593 local remote_recycle_path=" ${BOX_DIR%/ } /${RECYCLE_BIN_DIR%/ } "
584- local ssh_direct_opts=(-o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=30 -n)
585594 local date_folders
586- date_folders=$( ssh " ${SSH_OPTS_ARRAY[@]} " " ${ssh_direct_opts [@]} " " $BOX_ADDR " " ls -1 \" $remote_recycle_path \" " 2> /dev/null) || true
595+ date_folders=$( ssh " ${SSH_OPTS_ARRAY[@]} " " ${SSH_DIRECT_OPTS [@]} " " $BOX_ADDR " " ls -1 \" $remote_recycle_path \" " 2> /dev/null) || true
587596 if [[ -z " $date_folders " ]]; then
588597 echo " ❌ No dated folders found in the recycle bin. Nothing to restore." >&2
589598 return 1
@@ -719,10 +728,9 @@ run_recycle_bin_cleanup() {
719728 if [[ " ${RECYCLE_BIN_ENABLED:- false} " != " true" ]]; then return 0; fi
720729 log_message " Checking remote recycle bin..."
721730 local remote_cleanup_path=" ${BOX_DIR%/ } /${RECYCLE_BIN_DIR%/ } "
722- local ssh_direct_opts=(-o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=30 -n)
723731 local list_command=" ls -1 \" $remote_cleanup_path \" "
724732 local all_folders
725- all_folders=$( ssh " ${SSH_OPTS_ARRAY[@]} " " ${ssh_direct_opts [@]} " " $BOX_ADDR " " $list_command " 2>> " ${LOG_FILE:-/ dev/ null} " ) || {
733+ all_folders=$( ssh " ${SSH_OPTS_ARRAY[@]} " " ${SSH_DIRECT_OPTS [@]} " " $BOX_ADDR " " $list_command " 2>> " ${LOG_FILE:-/ dev/ null} " ) || {
726734 log_message " Recycle bin not found or unable to list contents. Nothing to clean."
727735 return 0
728736 }
@@ -736,11 +744,11 @@ run_recycle_bin_cleanup() {
736744 local threshold_timestamp
737745 threshold_timestamp=$( date -d " $retention_days days ago" +%s)
738746 while IFS= read -r folder; do
739- if [[ " $folder " =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && folder_timestamp=$( date -d " $folder " +%s 2> /dev/null) ; then
740- if (( folder_timestamp < threshold_timestamp )) ; then
741- folders_to_delete+=" ${folder} " $' \n '
742- fi
743- fi
747+ if [[ " $folder " =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && folder_timestamp=$( date -d " $folder " +%s 2> /dev/null) && [[ -n " $folder_timestamp " ]] ; then
748+ if (( folder_timestamp < threshold_timestamp )) ; then
749+ folders_to_delete+=" ${folder} " $' \n '
750+ fi
751+ fi
744752 done <<< " $all_folders"
745753 if [[ -n " $folders_to_delete " ]]; then
746754 log_message " Removing old recycle bin folders:"
@@ -750,8 +758,8 @@ run_recycle_bin_cleanup() {
750758 if [[ -n " $folder " ]]; then
751759 log_message " Deleting: $folder "
752760 local remote_dir_to_delete=" ${remote_cleanup_path} /${folder} /"
753- rsync -a --delete -e " $SSH_CMD " " $empty_dir /" " ${BOX_ADDR} :${remote_dir_to_delete} " > /dev/null 2>> " ${LOG_FILE:-/ dev/ null} "
754- ssh " ${SSH_OPTS_ARRAY[@]} " " ${ssh_direct_opts [@]} " " $BOX_ADDR " " rmdir \" $remote_dir_to_delete \" " 2>> " ${LOG_FILE:-/ dev/ null} "
761+ rsync -a --delete -e " $SSH_CMD " " $empty_dir /" " ${BOX_ADDR} :${remote_dir_to_delete} " > /dev/null 2>> " ${LOG_FILE:-/ dev/ null} "
762+ ssh " ${SSH_OPTS_ARRAY[@]} " " ${SSH_DIRECT_OPTS [@]} " " $BOX_ADDR " " rmdir \" $remote_dir_to_delete \" " 2>> " ${LOG_FILE:-/ dev/ null} "
755763 fi
756764 done <<< " $folders_to_delete"
757765
@@ -849,6 +857,9 @@ if [ -f "$LOG_FILE" ] && [ "$(stat -c%s "$LOG_FILE")" -gt "$max_log_size_bytes"
849857 find " $( dirname " $LOG_FILE " ) " -name " $( basename " $LOG_FILE " ) .*" -type f -mtime +" $LOG_RETENTION_DAYS " -delete
850858fi
851859
860+ log_message " Flushing filesystem buffers to disk..."
861+ sync
862+
852863echo " ============================================================" >> " $LOG_FILE "
853864log_message " Starting rsync backup..."
854865
0 commit comments