Skip to content

Commit 838baca

Browse files
authored
Merge pull request #30 from buildplan/improve_ssh
Add: SSH array and flush system cache before backup, improve: recycle bin cleanup
2 parents f2237dd + a890db3 commit 838baca

File tree

4 files changed

+49
-27
lines changed

4 files changed

+49
-27
lines changed

README.md

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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")
420420
fi
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
850858
fi
851859

860+
log_message "Flushing filesystem buffers to disk..."
861+
sync
862+
852863
echo "============================================================" >> "$LOG_FILE"
853864
log_message "Starting rsync backup..."
854865

backup.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# =================================================================
2-
# Configuration for rsync Backup Script v0.25
2+
# Configuration for rsync Backup Script v0.27
33
# =================================================================
44
# !! IMPORTANT !! Set file permissions to 600 (chmod 600 backup.conf)
55

backup_script.sh

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
# ===================== v0.26 - 2025.08.12 ========================
2+
# ===================== v0.27 - 2025.08.12 ========================
33
#
44
# Example backup.conf:
55
# BACKUP_DIRS="/home/user/test/./ /var/www/./"
@@ -145,6 +145,14 @@ if [[ -n "${BANDWIDTH_LIMIT_KBPS:-}" && "${BANDWIDTH_LIMIT_KBPS}" -gt 0 ]]; then
145145
RSYNC_BASE_OPTS+=(--bwlimit="$BANDWIDTH_LIMIT_KBPS")
146146
fi
147147

148+
# Shared options for direct, non-interactive SSH commands
149+
SSH_DIRECT_OPTS=(
150+
-o StrictHostKeyChecking=no
151+
-o BatchMode=yes
152+
-o ConnectTimeout=30
153+
-n
154+
)
155+
148156
# =================================================================
149157
# HELPER FUNCTIONS
150158
# =================================================================
@@ -235,6 +243,8 @@ run_preflight_checks() {
235243
if [[ "$check_failed" == "true" ]]; then exit 10; fi
236244
if [[ "$test_mode" == "true" ]]; then echo "✅ All required commands are present."; fi
237245
if [[ "$test_mode" == "true" ]]; then echo "--- Checking SSH connectivity..."; fi
246+
247+
# Quick preflight connectivity "ping": short 10s timeout for fail-fast behaviour
238248
if ! ssh "${SSH_OPTS_ARRAY[@]}" -o BatchMode=yes -o ConnectTimeout=10 "$BOX_ADDR" 'exit' 2>/dev/null; then
239249
local err_msg="Unable to SSH into $BOX_ADDR. Check keys and connectivity."
240250
if [[ "$test_mode" == "true" ]]; then echo "$err_msg"; else send_notification "❌ SSH FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "$err_msg"; fi; exit 6
@@ -307,9 +317,8 @@ run_restore_mode() {
307317
if [[ "$dir_choice" == "$RECYCLE_OPTION" ]]; then
308318
echo "--- Browse Recycle Bin ---"
309319
local remote_recycle_path="${BOX_DIR%/}/${RECYCLE_BIN_DIR%/}"
310-
local ssh_direct_opts=(-o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=30 -n)
311320
local date_folders
312-
date_folders=$(ssh "${SSH_OPTS_ARRAY[@]}" "${ssh_direct_opts[@]}" "$BOX_ADDR" "ls -1 \"$remote_recycle_path\"" 2>/dev/null) || true
321+
date_folders=$(ssh "${SSH_OPTS_ARRAY[@]}" "${SSH_DIRECT_OPTS[@]}" "$BOX_ADDR" "ls -1 \"$remote_recycle_path\"" 2>/dev/null) || true
313322
if [[ -z "$date_folders" ]]; then
314323
echo "❌ No dated folders found in the recycle bin. Nothing to restore." >&2
315324
return 1
@@ -445,10 +454,9 @@ run_recycle_bin_cleanup() {
445454
if [[ "${RECYCLE_BIN_ENABLED:-false}" != "true" ]]; then return 0; fi
446455
log_message "Checking remote recycle bin..."
447456
local remote_cleanup_path="${BOX_DIR%/}/${RECYCLE_BIN_DIR%/}"
448-
local ssh_direct_opts=(-o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=30 -n)
449457
local list_command="ls -1 \"$remote_cleanup_path\""
450458
local all_folders
451-
all_folders=$(ssh "${SSH_OPTS_ARRAY[@]}" "${ssh_direct_opts[@]}" "$BOX_ADDR" "$list_command" 2>> "${LOG_FILE:-/dev/null}") || {
459+
all_folders=$(ssh "${SSH_OPTS_ARRAY[@]}" "${SSH_DIRECT_OPTS[@]}" "$BOX_ADDR" "$list_command" 2>> "${LOG_FILE:-/dev/null}") || {
452460
log_message "Recycle bin not found or unable to list contents. Nothing to clean."
453461
return 0
454462
}
@@ -462,11 +470,11 @@ run_recycle_bin_cleanup() {
462470
local threshold_timestamp
463471
threshold_timestamp=$(date -d "$retention_days days ago" +%s)
464472
while IFS= read -r folder; do
465-
if [[ "$folder" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && folder_timestamp=$(date -d "$folder" +%s 2>/dev/null); then
466-
if (( folder_timestamp < threshold_timestamp )); then
467-
folders_to_delete+="${folder}"$'\n'
468-
fi
469-
fi
473+
if [[ "$folder" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && folder_timestamp=$(date -d "$folder" +%s 2>/dev/null) && [[ -n "$folder_timestamp" ]]; then
474+
if (( folder_timestamp < threshold_timestamp )); then
475+
folders_to_delete+="${folder}"$'\n'
476+
fi
477+
fi
470478
done <<< "$all_folders"
471479
if [[ -n "$folders_to_delete" ]]; then
472480
log_message "Removing old recycle bin folders:"
@@ -476,8 +484,8 @@ run_recycle_bin_cleanup() {
476484
if [[ -n "$folder" ]]; then
477485
log_message " Deleting: $folder"
478486
local remote_dir_to_delete="${remote_cleanup_path}/${folder}/"
479-
rsync -a --delete -e "$SSH_CMD" "$empty_dir/" "${BOX_ADDR}:${remote_dir_to_delete}" >/dev/null 2>> "${LOG_FILE:-/dev/null}"
480-
ssh "${SSH_OPTS_ARRAY[@]}" "${ssh_direct_opts[@]}" "$BOX_ADDR" "rmdir \"$remote_dir_to_delete\"" 2>> "${LOG_FILE:-/dev/null}"
487+
rsync -a --delete -e "$SSH_CMD" "$empty_dir/" "${BOX_ADDR}:${remote_dir_to_delete}" >/dev/null 2>> "${LOG_FILE:-/dev/null}"
488+
ssh "${SSH_OPTS_ARRAY[@]}" "${SSH_DIRECT_OPTS[@]}" "$BOX_ADDR" "rmdir \"$remote_dir_to_delete\"" 2>> "${LOG_FILE:-/dev/null}"
481489
fi
482490
done <<< "$folders_to_delete"
483491

@@ -575,6 +583,9 @@ if [ -f "$LOG_FILE" ] && [ "$(stat -c%s "$LOG_FILE")" -gt "$max_log_size_bytes"
575583
find "$(dirname "$LOG_FILE")" -name "$(basename "$LOG_FILE").*" -type f -mtime +"$LOG_RETENTION_DAYS" -delete
576584
fi
577585

586+
log_message "Flushing filesystem buffers to disk..."
587+
sync
588+
578589
echo "============================================================" >> "$LOG_FILE"
579590
log_message "Starting rsync backup..."
580591

backup_script.sh.sha256

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0437596607548aa6a9d04943f32bb8883d64863c963c538b099e8bf5bd97ddac backup_script.sh
1+
a7958073ec67b436a92a904e551aa4358323a5096bcce29b69062bae3bdb6421 backup_script.sh

0 commit comments

Comments
 (0)