Read the byte count rsync actually prints, not the word "bytes"

--stats prints "Total transferred file size: 1,234,567 bytes", so $NF is the
unit word; stripping non-digits from it left an empty string and ""+0 is 0.
Every transfer ever logged recorded zero. Nothing looked broken — the history
filled with 1,423 correct rows all reading 0, the graph drew a flat line, and
DIGEST_SMART_ON_BANDWIDTH could never fire because 0 is never above 50GB.
Both parse sites now share one program, since fixing either alone would have
left the other silently wrong.
This commit is contained in:
Gmer4Lfe
2026-08-14 17:29:30 -04:00
parent a71723e51f
commit 976fdf6e50
+24 -2
View File
@@ -449,6 +449,28 @@ done
# Add --stats to capture bytes transferred for bandwidth logging # Add --stats to capture bytes transferred for bandwidth logging
RSYNC_OPTS+=(--stats) RSYNC_OPTS+=(--stats)
# How the byte count is read back out of --stats. Both parse sites share this, because they had
# the same bug and fixing one would have left the other silently wrong.
#
# rsync prints: Total transferred file size: 1,234,567 bytes
# so $NF is the word "bytes". The previous version stripped non-digits from $NF, which left an
# empty string, and "" + 0 is 0 — every transfer ever logged recorded 0 bytes. Nothing failed:
# bandwidth_history.db filled up correctly with 1,423 rows all reading zero, the graph plotted a
# flat line, and DIGEST_SMART_ON_BANDWIDTH could never fire because 0 is never above
# BANDWIDTH_WARN_GB. A whole feature that ran on schedule and measured nothing.
#
# Walks back from the end and takes the first field that is entirely digits once commas are
# removed, rather than trusting a fixed position: the units word is not guaranteed to be present
# on every rsync build, and $(NF-1) would then be as wrong as $NF is now.
VV_RSYNC_BYTES_AWK='
/Total transferred file size:/ {
for (i = NF; i > 0; i--) {
v = $i; gsub(/,/, "", v)
if (v ~ /^[0-9]+$/) { print v + 0; exit }
}
print 0; exit
}'
[[ "$DRY_RUN" == true ]] && RSYNC_OPTS+=("--dry-run") [[ "$DRY_RUN" == true ]] && RSYNC_OPTS+=("--dry-run")
# ── Merge pass 1: pull remote-unique content to local (--ignore-existing) ──────────────────── # ── Merge pass 1: pull remote-unique content to local (--ignore-existing) ────────────────────
@@ -463,7 +485,7 @@ if [[ "$MERGE_RUN" == true ]]; then
"root@${REMOTE_SERVER}:${DIRECTORY}/" "${DIRECTORY}/" 2>&1) "root@${REMOTE_SERVER}:${DIRECTORY}/" "${DIRECTORY}/" 2>&1)
_pull_exit=$? _pull_exit=$?
_pull_bytes=$(echo "$_pull_output" | \ _pull_bytes=$(echo "$_pull_output" | \
awk '/Total transferred file size:/{gsub(/,/,"",$NF); gsub(/[^0-9]/,"",$NF); print $NF+0}') awk "$VV_RSYNC_BYTES_AWK")
_pull_complete=false _pull_complete=false
if [[ "$_pull_exit" -eq 0 ]]; then if [[ "$_pull_exit" -eq 0 ]]; then
echo "$ICON_DONE Merge pass 1 complete — ${_pull_bytes:-0} bytes pulled" echo "$ICON_DONE Merge pass 1 complete — ${_pull_bytes:-0} bytes pulled"
@@ -518,7 +540,7 @@ for (( ATTEMPT=1; ATTEMPT<=RETRY_COUNT; ATTEMPT++ )); do
if [[ "$RSYNC_EXIT" -eq 0 ]]; then if [[ "$RSYNC_EXIT" -eq 0 ]]; then
# Parse bytes transferred from --stats output # Parse bytes transferred from --stats output
BYTES_TRANSFERRED=$(echo "$RSYNC_OUTPUT" | \ BYTES_TRANSFERRED=$(echo "$RSYNC_OUTPUT" | \
awk '/Total transferred file size:/{gsub(/,/,"",$NF); gsub(/[^0-9]/,"",$NF); print $NF+0}') awk "$VV_RSYNC_BYTES_AWK")
BYTES_TRANSFERRED="${BYTES_TRANSFERRED:-0}" BYTES_TRANSFERRED="${BYTES_TRANSFERRED:-0}"
echo "$ICON_DONE Rsync complete — $BYTES_TRANSFERRED bytes transferred" echo "$ICON_DONE Rsync complete — $BYTES_TRANSFERRED bytes transferred"