Skip to main content

Exit Codes, Locking, and Idempotency

Good automation is safe to retry and easy to reason about when jobs fail.

Script Pattern

rclone-job-wrapper.sh
#!/usr/bin/env bash
set -euo pipefail

lockfile="/var/lock/rclone-backup.lock"
exec 9>"$lockfile"
flock -n 9 || { echo "job already running"; exit 1; }

rclone sync /srv/data remote-prod:backup/data --log-file /var/log/rclone-job.log
rclone check /srv/data remote-prod:backup/data --one-way

Why Locking Matters

Without lockWith lock
Overlapping jobs compete for bandwidthSingle in-flight transfer
Hard-to-explain delete behaviorDeterministic run order
Race conditions in post-check stepsClean success/failure lifecycle

Idempotency Rules

  1. Use fixed source and destination mappings.
  2. Keep job flags consistent between runs.
  3. Log every run with timestamp or unique ID.
  4. Make cleanup explicit, never implicit.

Mapping

tip

Treat rclone sync like a database migration: controlled, logged, and reviewable.

Common Pitfalls

PitfallConsequencePrevention
No set -euo pipefailPartial failure goes unnoticedEnable strict shell mode
No lock fileConcurrent destructive runsUse flock or equivalent mutex
Ignoring exit code in schedulerFalse success reportingAlert on non-zero status

What's Next