Skip to content

Commit 19839f5

Browse files
authored
Merge pull request #13 from buildplan/improve
Improvements made to format_backup_stats()
2 parents 411554a + 03e4d2d commit 19839f5

File tree

2 files changed

+34
-32
lines changed

2 files changed

+34
-32
lines changed

README.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ END_EXCLUDES
222222

223223
# =================================================================
224224
# SCRIPT INITIALIZATION & SETUP
225-
# v0.10 - 2025.08.09
225+
# v0.11 - 2025.08.09
226226
# =================================================================
227227
set -Euo pipefail
228228
umask 077
@@ -330,7 +330,7 @@ send_notification() {
330330

331331
run_integrity_check() {
332332
local rsync_check_opts=(-ainc -c --delete --exclude-from="$EXCLUDE_FILE_TMP" --out-format="%n" -e "ssh ${SSH_OPTS_STR:-}")
333-
333+
334334
for dir in $BACKUP_DIRS; do
335335
local remote_subdir="${REMOTE_TARGET}/$(basename "$dir")/"
336336
# shellcheck disable=SC2086
@@ -351,14 +351,15 @@ parse_stat() {
351351
format_backup_stats() {
352352
local rsync_output="$1"
353353

354-
local bytes_transferred=$(parse_stat "$rsync_output" 'Total_transferred_size:' '{print $2}')
355-
local files_created=$(parse_stat "$rsync_output" 'Number_of_created_files:' '{print $2}')
356-
local files_deleted=$(parse_stat "$rsync_output" 'Number_of_deleted_files:' '{print $2}')
354+
local bytes_transferred=$(parse_stat "$rsync_output" 'Total_transferred_size:' '{s+=$2} END {print s}')
355+
local files_created=$(parse_stat "$rsync_output" 'Number_of_created_files:' '{s+=$2} END {print s}')
356+
local files_deleted=$(parse_stat "$rsync_output" 'Number_of_deleted_files:' '{s+=$2} END {print s}')
357357

358+
# Fallback for older rsync versions
358359
if [[ -z "$bytes_transferred" && -z "$files_created" && -z "$files_deleted" ]]; then
359-
bytes_transferred=$(parse_stat "$rsync_output" 'Total transferred file size:' '{gsub(/,/, ""); print $5}')
360-
files_created=$(parse_stat "$rsync_output" 'Number of created files:' '{print $5}')
361-
files_deleted=$(parse_stat "$rsync_output" 'Number of deleted files:' '{print $5}')
360+
bytes_transferred=$(parse_stat "$rsync_output" 'Total transferred file size:' '{gsub(/,/, ""); s+=$5} END {print s}')
361+
files_created=$(parse_stat "$rsync_output" 'Number of created files:' '{s+=$5} END {print s}')
362+
files_deleted=$(parse_stat "$rsync_output" 'Number of deleted files:' '{s+=$5} END {print s}')
362363
fi
363364

364365
local stats_summary=""
@@ -373,7 +374,7 @@ format_backup_stats() {
373374
}
374375

375376
cleanup() {
376-
rm -f "${EXCLUDE_FILE_TMP:-}" "${RSYNC_LOG_TMP:-}"
377+
rm -f "${EXCLUDE_FILE_TMP:-}"
377378
}
378379

379380
# =================================================================
@@ -383,7 +384,7 @@ cleanup() {
383384
trap cleanup EXIT
384385
trap 'send_notification "❌ Backup Crashed: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "Backup script terminated unexpectedly. Check log: ${LOG_FILE:-/dev/null}"' ERR
385386

386-
REQUIRED_CMDS=(rsync curl flock hostname date stat mv touch awk numfmt grep printf nice ionice sed mktemp)
387+
REQUIRED_CMDS=(rsync curl flock hostname date stat mv touch awk numfmt grep printf nice ionice sed mktemp basename)
387388
for cmd in "${REQUIRED_CMDS[@]}"; do
388389
if ! command -v "$cmd" &>/dev/null; then
389390
echo "FATAL: Required command '$cmd' not found. Please install it." >&2; trap - ERR; exit 10
@@ -396,7 +397,7 @@ if ! ssh ${SSH_OPTS_STR:-} -o BatchMode=yes -o ConnectTimeout=10 "$HETZNER_BOX"
396397
fi
397398

398399
for dir in $BACKUP_DIRS; do
399-
if [[ ! -d "$dir" ]] || [[ "$dir" != */ ]]; then
400+
if [[ ! -d "$dir" ]] || [[ "$dir" != */ ]]; then
400401
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 ('/')."
401402
trap - ERR; exit 2
402403
fi
@@ -440,7 +441,7 @@ if [[ "${1:-}" ]]; then
440441
echo "--- INTEGRITY CHECK MODE ACTIVATED ---"
441442
echo "Calculating differences..."
442443
FILE_DISCREPANCIES=$(run_integrity_check)
443-
444+
444445
if [[ "$1" == "--summary" ]]; then
445446
MISMATCH_COUNT=$(echo "$FILE_DISCREPANCIES" | wc -l)
446447
printf "🚨 Total files with checksum mismatches: %d\n" "$MISMATCH_COUNT"
@@ -484,9 +485,9 @@ full_rsync_output=""
484485

485486
for dir in $BACKUP_DIRS; do
486487
log_message "Backing up directory: $dir"
487-
488+
488489
remote_subdir="${REMOTE_TARGET}/$(basename "$dir")/"
489-
490+
490491
RSYNC_LOG_TMP=$(mktemp)
491492
RSYNC_EXIT_CODE=0
492493
RSYNC_OPTS=("${RSYNC_BASE_OPTS[@]}")
@@ -510,12 +511,12 @@ for dir in $BACKUP_DIRS; do
510511
success_dirs+=("$(basename "$dir")")
511512
if [[ $RSYNC_EXIT_CODE -eq 24 ]]; then
512513
log_message "WARNING for $dir: rsync completed with code 24 (some source files vanished)."
513-
overall_exit_code=24 # Mark the overall run as a warning
514+
overall_exit_code=24
514515
fi
515516
else
516517
failed_dirs+=("$(basename "$dir")")
517518
log_message "FAILED for $dir: rsync exited with code: $RSYNC_EXIT_CODE."
518-
overall_exit_code=1 # Mark the overall run as a failure
519+
overall_exit_code=1
519520
fi
520521
done
521522

backup_script.sh

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

33
# =================================================================
44
# SCRIPT INITIALIZATION & SETUP
5-
# v0.10 - 2025.08.09
5+
# v0.11 - 2025.08.09
66
# =================================================================
77
set -Euo pipefail
88
umask 077
@@ -110,7 +110,7 @@ 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-
113+
114114
for dir in $BACKUP_DIRS; do
115115
local remote_subdir="${REMOTE_TARGET}/$(basename "$dir")/"
116116
# shellcheck disable=SC2086
@@ -131,14 +131,15 @@ parse_stat() {
131131
format_backup_stats() {
132132
local rsync_output="$1"
133133

134-
local bytes_transferred=$(parse_stat "$rsync_output" 'Total_transferred_size:' '{print $2}')
135-
local files_created=$(parse_stat "$rsync_output" 'Number_of_created_files:' '{print $2}')
136-
local files_deleted=$(parse_stat "$rsync_output" 'Number_of_deleted_files:' '{print $2}')
134+
local bytes_transferred=$(parse_stat "$rsync_output" 'Total_transferred_size:' '{s+=$2} END {print s}')
135+
local files_created=$(parse_stat "$rsync_output" 'Number_of_created_files:' '{s+=$2} END {print s}')
136+
local files_deleted=$(parse_stat "$rsync_output" 'Number_of_deleted_files:' '{s+=$2} END {print s}')
137137

138+
# Fallback for older rsync versions
138139
if [[ -z "$bytes_transferred" && -z "$files_created" && -z "$files_deleted" ]]; then
139-
bytes_transferred=$(parse_stat "$rsync_output" 'Total transferred file size:' '{gsub(/,/, ""); print $5}')
140-
files_created=$(parse_stat "$rsync_output" 'Number of created files:' '{print $5}')
141-
files_deleted=$(parse_stat "$rsync_output" 'Number of deleted files:' '{print $5}')
140+
bytes_transferred=$(parse_stat "$rsync_output" 'Total transferred file size:' '{gsub(/,/, ""); s+=$5} END {print s}')
141+
files_created=$(parse_stat "$rsync_output" 'Number of created files:' '{s+=$5} END {print s}')
142+
files_deleted=$(parse_stat "$rsync_output" 'Number of deleted files:' '{s+=$5} END {print s}')
142143
fi
143144

144145
local stats_summary=""
@@ -153,7 +154,7 @@ format_backup_stats() {
153154
}
154155

155156
cleanup() {
156-
rm -f "${EXCLUDE_FILE_TMP:-}" "${RSYNC_LOG_TMP:-}"
157+
rm -f "${EXCLUDE_FILE_TMP:-}"
157158
}
158159

159160
# =================================================================
@@ -163,7 +164,7 @@ cleanup() {
163164
trap cleanup EXIT
164165
trap 'send_notification "❌ Backup Crashed: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "Backup script terminated unexpectedly. Check log: ${LOG_FILE:-/dev/null}"' ERR
165166

166-
REQUIRED_CMDS=(rsync curl flock hostname date stat mv touch awk numfmt grep printf nice ionice sed mktemp)
167+
REQUIRED_CMDS=(rsync curl flock hostname date stat mv touch awk numfmt grep printf nice ionice sed mktemp basename)
167168
for cmd in "${REQUIRED_CMDS[@]}"; do
168169
if ! command -v "$cmd" &>/dev/null; then
169170
echo "FATAL: Required command '$cmd' not found. Please install it." >&2; trap - ERR; exit 10
@@ -176,7 +177,7 @@ if ! ssh ${SSH_OPTS_STR:-} -o BatchMode=yes -o ConnectTimeout=10 "$HETZNER_BOX"
176177
fi
177178

178179
for dir in $BACKUP_DIRS; do
179-
if [[ ! -d "$dir" ]] || [[ "$dir" != */ ]]; then
180+
if [[ ! -d "$dir" ]] || [[ "$dir" != */ ]]; then
180181
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 ('/')."
181182
trap - ERR; exit 2
182183
fi
@@ -220,7 +221,7 @@ if [[ "${1:-}" ]]; then
220221
echo "--- INTEGRITY CHECK MODE ACTIVATED ---"
221222
echo "Calculating differences..."
222223
FILE_DISCREPANCIES=$(run_integrity_check)
223-
224+
224225
if [[ "$1" == "--summary" ]]; then
225226
MISMATCH_COUNT=$(echo "$FILE_DISCREPANCIES" | wc -l)
226227
printf "🚨 Total files with checksum mismatches: %d\n" "$MISMATCH_COUNT"
@@ -264,9 +265,9 @@ full_rsync_output=""
264265

265266
for dir in $BACKUP_DIRS; do
266267
log_message "Backing up directory: $dir"
267-
268+
268269
remote_subdir="${REMOTE_TARGET}/$(basename "$dir")/"
269-
270+
270271
RSYNC_LOG_TMP=$(mktemp)
271272
RSYNC_EXIT_CODE=0
272273
RSYNC_OPTS=("${RSYNC_BASE_OPTS[@]}")
@@ -290,12 +291,12 @@ for dir in $BACKUP_DIRS; do
290291
success_dirs+=("$(basename "$dir")")
291292
if [[ $RSYNC_EXIT_CODE -eq 24 ]]; then
292293
log_message "WARNING for $dir: rsync completed with code 24 (some source files vanished)."
293-
overall_exit_code=24 # Mark the overall run as a warning
294+
overall_exit_code=24
294295
fi
295296
else
296297
failed_dirs+=("$(basename "$dir")")
297298
log_message "FAILED for $dir: rsync exited with code: $RSYNC_EXIT_CODE."
298-
overall_exit_code=1 # Mark the overall run as a failure
299+
overall_exit_code=1
299300
fi
300301
done
301302

0 commit comments

Comments
 (0)