USB Cold-Backup Scripts (Expansion24 / Expansion26)
Overview
Two UnRAID User Scripts mirror array shares to two USB-attached cold-backup drives via rclone sync. Both scripts were extended with Pushover push notifications on completion (success or failure), since User Scripts has no built-in alerting.
Backup Mapping
| Target Drive | Shares Covered |
|---|---|
| Expansion24 (24TB) | Data (full), Photos, Multimedia/Movies, Multimedia/ST |
| Expansion26 (26TB) | Multimedia/Audio, Multimedia/Books, Multimedia/Personal, Multimedia/TV, Multimedia/To Review, Multimedia/Ubooquity, Multimedia/audiobookshelf |
Script Logic (both jobs share this pattern)
#!/bin/bash
# === Pushover Config ===
PUSHOVER_TOKEN="<redacted — see Pushover application dashboard>"
PUSHOVER_USER="<redacted — user key, not stored in script comments>"
FAILED_JOBS=""
START_TIME=$(date +%s)
send_pushover() {
local STATUS="$1"
local MESSAGE="$2"
curl -s \
--form-string "token=${PUSHOVER_TOKEN}" \
--form-string "user=${PUSHOVER_USER}" \
--form-string "title=UnRAID Backup - <ExpansionXX>" \
--form-string "message=${MESSAGE}" \
--form-string "priority=$( [ "$STATUS" = "FAIL" ] && echo 1 || echo 0 )" \
https://api.pushover.net/1/messages.json > /dev/null
}
run_sync() {
local SRC="$1" DEST="$2" LOG="$3" LABEL="$4"
rclone sync "$SRC" "$DEST" --log-file="$LOG" -v
if [ $? -ne 0 ]; then
FAILED_JOBS="${FAILED_JOBS}\n- ${LABEL}"
fi
}
# One run_sync call per share/subfolder pair...
END_TIME=$(date +%s)
DURATION=$(( (END_TIME - START_TIME) / 60 ))
if [ -z "$FAILED_JOBS" ]; then
send_pushover "OK" "All jobs completed successfully in ${DURATION} min."
else
send_pushover "FAIL" "Backup finished with failures in ${DURATION} min.\nFailed jobs:${FAILED_JOBS}"
fi
Key design points:
- Each
rclone synccall is wrapped inrun_sync(), capturing its own exit code — a failure in job 2 of 7 doesn't mask or get overwritten by job 7's exit code. - All jobs run independently to completion regardless of earlier failures (no
set -e) — by design, so one broken share doesn't block backups of everything else. - A single Pushover notification fires at the end summarizing success or listing exactly which job(s) failed, with failure notifications set to
priority=1to bypass Pushover quiet hours.
Notes / Gotchas
- Both
PUSHOVER_TOKENandPUSHOVER_USERshould be redacted from any wiki copy of this script — store actual credentials in the User Scripts plugin directly, not in a doc that might get exported or shared. $?only reflects the immediately preceding command — if a future edit pipesrcloneoutput through another command (| tee,| grep, etc.), the exit code capture breaks silently. Keep the exit-code check directly after therclonecall.- These backups are not parity-protected — they live on Unassigned Devices, outside the array. A single backup drive failure has no recovery path other than re-running the sync from source.
Last Updated
2026-06-23
No comments to display
No comments to display