Skip to content

Commit f803b65

Browse files
authored
Update backup_script.sh
1 parent 1ee5df2 commit f803b65

File tree

1 file changed

+37
-32
lines changed

1 file changed

+37
-32
lines changed

backup_script.sh

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# =================================================================
44
# SCRIPT INITIALIZATION & SETUP
5-
# v0.8 - 2025.08.09
5+
# v0.9 - 2025.08.09
66
# =================================================================
77
set -Euo pipefail
88
umask 077
@@ -47,7 +47,7 @@ else
4747
fi
4848

4949
# --- Validate that all required configuration variables are set ---
50-
for var in LOCAL_DIR BOX_DIR HETZNER_BOX SSH_OPTS_STR LOG_FILE \
50+
for var in BACKUP_DIRS BOX_DIR HETZNER_BOX SSH_OPTS_STR LOG_FILE \
5151
NTFY_PRIORITY_SUCCESS NTFY_PRIORITY_WARNING NTFY_PRIORITY_FAILURE \
5252
LOG_RETENTION_DAYS; do
5353
if [ -z "${!var:-}" ]; then
@@ -110,7 +110,8 @@ send_notification() {
110110

111111
run_integrity_check() {
112112
local rsync_check_opts=(-ainc -c --delete --exclude-from="$EXCLUDE_FILE_TMP" --out-format="%n" -e "ssh ${SSH_OPTS_STR:-}")
113-
LC_ALL=C rsync "${rsync_check_opts[@]}" "$LOCAL_DIR" "$REMOTE_TARGET" 2>> "${LOG_FILE:-/dev/null}"
113+
# shellcheck disable=SC2086
114+
LC_ALL=C rsync "${rsync_check_opts[@]}" $BACKUP_DIRS "$REMOTE_TARGET" 2>> "${LOG_FILE:-/dev/null}"
114115
}
115116

116117
parse_stat() {
@@ -170,10 +171,12 @@ if ! ssh ${SSH_OPTS_STR:-} -o BatchMode=yes -o ConnectTimeout=10 "$HETZNER_BOX"
170171
trap - ERR; exit 6
171172
fi
172173

173-
if [[ ! -d "$LOCAL_DIR" ]] || [[ "$LOCAL_DIR" != */ ]]; then
174-
send_notification "❌ Backup FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "FATAL: LOCAL_DIR must exist and end with a trailing slash ('/')."
175-
trap - ERR; exit 2
176-
fi
174+
for dir in $BACKUP_DIRS; do
175+
if [[ ! -d "$dir" ]] || [[ "$dir" != */ ]]; then
176+
send_notification "❌ Backup FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "FATAL: A directory in BACKUP_DIRS ('$dir') must exist and end with a trailing slash ('/')."
177+
trap - ERR; exit 2
178+
fi
179+
done
177180

178181

179182
# =================================================================
@@ -192,37 +195,38 @@ if [[ "${1:-}" ]]; then
192195
--dry-run)
193196
trap - ERR
194197
echo "--- DRY RUN MODE ACTIVATED ---"
195-
if ! rsync "${RSYNC_BASE_OPTS[@]}" --dry-run --info=progress2 "$LOCAL_DIR" "$REMOTE_TARGET"; then
198+
# shellcheck disable=SC2086
199+
if ! rsync "${RSYNC_BASE_OPTS[@]}" --dry-run --info=progress2 $BACKUP_DIRS "$REMOTE_TARGET"; then
196200
echo ""
197201
echo "❌ Dry run FAILED. See the rsync error message above for details."
198202
exit 1
199203
fi
200204
echo "--- DRY RUN COMPLETED ---"; exit 0 ;;
201-
--checksum)
205+
--checksum | --summary)
206+
# Both modes use the same check, just with different reporting
202207
echo "--- INTEGRITY CHECK MODE ACTIVATED ---"
203-
echo "Comparing checksums... this may take a while."
208+
echo "Calculating differences..."
204209
FILE_DISCREPANCIES=$(run_integrity_check)
205-
if [ -z "$FILE_DISCREPANCIES" ]; then
206-
echo "✅ Checksum validation passed. No discrepancies found."
207-
log_message "Checksum validation passed. No discrepancies found."
208-
send_notification "✅ Backup Integrity OK: ${HOSTNAME}" "white_check_mark" "${NTFY_PRIORITY_SUCCESS}" "success" "Checksum validation passed. No discrepancies found."
209-
else
210-
log_message "Backup integrity check FAILED. Found discrepancies."
211-
ISSUE_LIST=$(echo "${FILE_DISCREPANCIES}" | head -n 10)
212-
printf "❌ Backup integrity check FAILED. First 10 differing files:\n%s\n" "${ISSUE_LIST}"
213-
printf -v FAILURE_MSG "Backup integrity check FAILED.\n\nFirst 10 differing files:\n%s\n\nCheck log for full details." "${ISSUE_LIST}"
214-
send_notification "❌ Backup Integrity FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "${FAILURE_MSG}"
210+
211+
if [[ "$1" == "--summary" ]]; then
212+
MISMATCH_COUNT=$(echo "$FILE_DISCREPANCIES" | wc -l)
213+
printf "🚨 Total files with checksum mismatches: %d\n" "$MISMATCH_COUNT"
214+
log_message "Summary mode check found $MISMATCH_COUNT mismatched files."
215+
send_notification "📊 Backup Summary: ${HOSTNAME}" "bar_chart" "${NTFY_PRIORITY_SUCCESS}" "success" "Mismatched files found: $MISMATCH_COUNT"
216+
else # --checksum
217+
if [ -z "$FILE_DISCREPANCIES" ]; then
218+
echo "✅ Checksum validation passed. No discrepancies found."
219+
log_message "Checksum validation passed. No discrepancies found."
220+
send_notification "✅ Backup Integrity OK: ${HOSTNAME}" "white_check_mark" "${NTFY_PRIORITY_SUCCESS}" "success" "Checksum validation passed. No discrepancies found."
221+
else
222+
log_message "Backup integrity check FAILED. Found discrepancies."
223+
ISSUE_LIST=$(echo "${FILE_DISCREPANCIES}" | head -n 10)
224+
printf "❌ Backup integrity check FAILED. First 10 differing files:\n%s\n" "${ISSUE_LIST}"
225+
printf -v FAILURE_MSG "Backup integrity check FAILED.\n\nFirst 10 differing files:\n%s\n\nCheck log for full details." "${ISSUE_LIST}"
226+
send_notification "❌ Backup Integrity FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "${FAILURE_MSG}"
227+
fi
215228
fi
216229
exit 0 ;;
217-
218-
--summary)
219-
echo "--- INTEGRITY SUMMARY MODE ---"
220-
echo "Calculating differences..."
221-
MISMATCH_COUNT=$(run_integrity_check | wc -l)
222-
printf "🚨 Total files with checksum mismatches: %d\n" "$MISMATCH_COUNT"
223-
log_message "Summary mode check found $MISMATCH_COUNT mismatched files."
224-
send_notification "📊 Backup Summary: ${HOSTNAME}" "bar_chart" "${NTFY_PRIORITY_SUCCESS}" "success" "Mismatched files found: $MISMATCH_COUNT"
225-
exit 0 ;;
226230
esac
227231
fi
228232

@@ -232,7 +236,6 @@ flock -n 200 || { echo "Another instance is running, exiting."; exit 5; }
232236
if [ -f "$LOG_FILE" ] && [ "$(stat -c%s "$LOG_FILE")" -gt "$MAX_LOG_SIZE" ]; then
233237
mv "$LOG_FILE" "${LOG_FILE}.$(date +%Y%m%d_%H%M%S)"
234238
touch "$LOG_FILE"
235-
# Clean up old log files
236239
find "$(dirname "$LOG_FILE")" -name "$(basename "$LOG_FILE").*" -type f -mtime +"$LOG_RETENTION_DAYS" -delete
237240
fi
238241

@@ -247,11 +250,13 @@ RSYNC_OPTS=("${RSYNC_BASE_OPTS[@]}")
247250

248251
if [[ "$VERBOSE_MODE" == "true" ]]; then
249252
RSYNC_OPTS+=(--info=stats2,progress2)
250-
nice -n 19 ionice -c 3 rsync "${RSYNC_OPTS[@]}" "$LOCAL_DIR" "$REMOTE_TARGET" 2>&1 | tee "$RSYNC_LOG_TMP"
253+
# shellcheck disable=SC2086
254+
nice -n 19 ionice -c 3 rsync "${RSYNC_OPTS[@]}" $BACKUP_DIRS "$REMOTE_TARGET" 2>&1 | tee "$RSYNC_LOG_TMP"
251255
RSYNC_EXIT_CODE=${PIPESTATUS[0]}
252256
else
253257
RSYNC_OPTS+=(--info=stats2)
254-
nice -n 19 ionice -c 3 rsync "${RSYNC_OPTS[@]}" "$LOCAL_DIR" "$REMOTE_TARGET" > "$RSYNC_LOG_TMP" 2>&1 || RSYNC_EXIT_CODE=$?
258+
# shellcheck disable=SC2086
259+
nice -n 19 ionice -c 3 rsync "${RSYNC_OPTS[@]}" $BACKUP_DIRS "$REMOTE_TARGET" > "$RSYNC_LOG_TMP" 2>&1 || RSYNC_EXIT_CODE=$?
255260
fi
256261

257262
END_TIME=$(date +%s)

0 commit comments

Comments
 (0)