C.W.K.
Stream
Lesson 12 of 12 · published

Practical Scripts: backup, deploy, daily-check

~13 min · practical, backup, deploy

Level 0Window Tourist
0 XP0/95 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

The shape of a real-world shell script

Production-grade shell scripts share a structure: defensive header, config block, helper functions, main flow, exit-time cleanup. Below are three patterns you can copy and adapt.

backup.sh — rsync to dated archive

#!/usr/bin/env bash
set -euo pipefail
src="${1:-$HOME}"
dest="${BACKUP_ROOT:-/Volumes/backup}/$(date +%Y/%m/%d)"
mkdir -p "$dest"
rsync -avzP --delete --exclude='.cache' "$src/" "$dest/"
echo "backup at $dest"

deploy.sh — test then push

#!/usr/bin/env bash
set -euo pipefail
log() { printf '%(%H:%M:%S)T %s\n' -1 "$*"; }
trap 'log "deploy failed at line $LINENO"' ERR
log 'running tests'
./test.sh
log 'pushing'
git push origin main
log 'done'

daily-check.sh — health gate

#!/usr/bin/env bash
set -euo pipefail
fail=0
checks=(
  'curl -sSf https://api.example/health'
  'pgrep -f my-worker'
  'df -P / | awk "NR==2 && \$5+0 < 90"'
)
for c in "${checks[@]}"; do
  if eval "$c" >/dev/null; then
    echo "✔ $c"
  else
    echo "✘ $c"
    fail=1
  fi
done
exit "$fail"

Pippa pattern

The pippa-working-scripts directory in cwkPippa follows the same shape: defensive header, lifecycle comment (# @pippa: persistent | purpose), small purpose-named files instead of date-prefixed scratch. Treat it as your reference for ergonomic shell scripts in 2026.

Code

Reusable header block·bash
#!/usr/bin/env bash
# @pippa: persistent | weekly backup of ~ to NAS
set -euo pipefail
IFS=$'\n\t'
HERE="$(cd "$(dirname "$0")" && pwd)"
log() { printf '%(%H:%M:%S)T %s\n' -1 "$*" >&2; }
die() { log "FATAL: $*"; exit 1; }
trap 'die "failed at line $LINENO"' ERR
# real work below
log 'starting'

External links

Exercise

Save the reusable header block as ~/bin/_template.sh. Use it to write a tiny backup.sh that rsyncs $HOME/notes/ to ~/Backups/notes-$(date +%F). Run it. Confirm it works under set -euo pipefail.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.