Lesson 8 / 25
if, elif, case and Short-Circuit Operators
Branch with if, case, && and ||.
Choosing a path
An if statement runs a command list and branches on its status: if cmd; then ...; elif other; then ...; else ...; fi. Any command can be a condition, not just tests: if grep -q ERROR app.log; then is idiomatic. case matches a value against glob patterns and is cleaner than long if/elif chains for things like command-line subcommands or file types: each branch ends with ;;, patterns can be combined with |, and *) is the default. Short-circuit operators chain commands: cmd1 && cmd2 runs cmd2 only if cmd1 succeeds; cmd1 || cmd2 runs cmd2 only if cmd1 fails, which is handy for mkdir -p dir || exit 1 or command -v jq >/dev/null || die "jq required". Avoid the a && b || c idiom as an if/else replacement: if b fails, c runs too. Use a real if when you mean if/else.
A subcommand dispatcher with case
Typical structure of a small CLI tool.
#!/usr/bin/env bash
set -euo pipefail
usage() { printf 'usage: %s {start|stop|status} [service]\n' "$0" >&2; exit 2; }
cmd="${1:-}"
service="${2:-web}"
case "$cmd" in
start) echo "starting $service" ;;
stop|halt) echo "stopping $service" ;;
status)
if systemctl is-active --quiet "$service"; then
echo "$service is running"
else
echo "$service is stopped"
fi
;;
-h|--help|"") usage ;;
*) echo "unknown command: $cmd" >&2; usage ;;
esacA railway points switch
case is a set of railway points: the train (value) is routed down exactly one track depending on its destination board (pattern), with a siding (*)) for anything unexpected.
Quick check: In `cmd1 || cmd2`, when does cmd2 run?
- Always
- Only if cmd1 succeeds
- Never
- Only if cmd1 fails
Answer
Only if cmd1 fails — || runs the right-hand command only when the left-hand one returns a non-zero status.