Exercises
Three short bash drills - safe arg parsing, a retrying curl, and a CSV summariser.
Three short challenges
EXAMPLE
#!/usr/bin/env bash
set -Eeuo pipefail
IFS=$'\n\t'
# 1. Argument parsing with getopts (POSIX), with long-flag-ish support
usage() {
cat <<'EOF'
usage: deploy.sh -e <env> [-d] [-t target]
-e env required: prod | staging | dev
-d dry run
-t target optional target (default: web)
EOF
}
env=''; dry=0; target='web'
while getopts ':e:dt:h' opt; do
case $opt in
e) env=$OPTARG ;;
d) dry=1 ;;
t) target=$OPTARG ;;
h) usage; exit 0 ;;
:) echo "missing arg for -$OPTARG" >&2; usage; exit 2 ;;
\?) echo "unknown -$OPTARG" >&2; usage; exit 2 ;;
esac
done
[[ -z $env ]] && { usage; exit 2; }
[[ $env =~ ^(prod|staging|dev)$ ]] || { echo 'bad env'; exit 2; }
echo "env=$env target=$target dry=$dry"
# 2. Retrying curl with exponential backoff and jitter
retry_curl() {
local url=$1 max=5 delay=1 i status body
for ((i=1; i<=max; i++)); do
body=$(curl -fsS --max-time 10 "$url" 2>/dev/null) && { echo "$body"; return 0; }
status=$?
if (( i < max )); then
sleep $((delay + RANDOM % 2))
delay=$((delay * 2))
fi
done
echo "failed after $max attempts" >&2
return 1
}
retry_curl 'https://example.com/healthz'
# 3. CSV summariser - sum + average + count by group
# Input format: category,amount (header row skipped)
# Usage: summarise.sh < sales.csv
{
read -r _header
declare -A sum count
while IFS=, read -r cat amount; do
[[ -z $cat || -z $amount ]] && continue
sum["$cat"]=$(awk -v a="${sum[$cat]:-0}" -v b="$amount" 'BEGIN { printf "%.2f", a + b }')
count["$cat"]=$((count["$cat"]+1))
done
printf '%-20s %10s %10s %12s\n' category n total avg
for cat in "${!sum[@]}"; do
n=${count[$cat]}; total=${sum[$cat]}
avg=$(awk -v t="$total" -v n="$n" 'BEGIN { printf "%.2f", t / n }')
printf '%-20s %10d %10s %12s\n' "$cat" "$n" "$total" "$avg"
done | sort
}
# Stretch: skip rows where amount is non-numeric and report skipped count to stderr.
Why it matters
These three drill the patterns most scripts need - safe args, network retries with backoff, and grouped aggregation without a shell library. After this, jq + awk + getopts is the muscle memory you reach for instead of reaching for Python.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…