Bash Scripting Deep Dive
Part of the DevOps Roadmap
In short
Your first scripts were a list of commands. Real automation scripts take flags, loop over servers, reuse functions and refuse to run with bad input. That's the jump this lesson makes.
Going beyond Phase 2's basics — functions, arrays, argument parsing, and proper error handling — turning ad-hoc one-liners into reliable, reusable automation scripts.

Think of it like this
The wedding caterer's master recipe
A wedding caterer doesn't rewrite the biryani recipe for every function. One master recipe takes 'number of guests' and 'spice level' as inputs, and calls smaller sub-recipes for raita and salan. A good Bash script works the same: arguments in, functions inside.
Watch it happen
Calls inside ./deploy.sh -e prod
Top of the stack is coloured
1/6The script starts. Top-level code acts like main.
The big ideas
What you need to know
Arrays hold lists
SERVERS=(web1 web2) and "${SERVERS[@]}" loop safely over every item, even ones with spaces.
getopts parses flags
getopts handles -e prod and -n in any order, so users don't have to remember argument positions.
Functions keep it tidy
Wrap repeated steps in functions. Use local inside them so variables don't leak into the rest of the script.
A dry-run flag
A -n flag that prints what would happen lets you test safely before touching real servers.
See it in code
Walk through the code
1#!/usr/bin/env bash2set -euo pipefail3usage() { echo "usage: $0 -e <env> [-n]" >&2; exit 2; }4DRY_RUN=false5while getopts "e:n" opt; do6 case "$opt" in7 e) ENV="$OPTARG" ;;8 n) DRY_RUN=true ;;9 *) usage ;;10 esac11done12[[ -z "${ENV:-}" ]] && usage13SERVERS=(web1 web2 web3)14for s in "${SERVERS[@]}"; do15 if $DRY_RUN; then echo "[dry-run] deploy $s ($ENV)"; else ssh "$s" "./deploy.sh $ENV"; fi16done1/4Strict mode, plus a usage function that prints help to stderr and exits with code 2.
Run ./deploy.sh -e staging -n first. Check the shellcheck tool too: it catches many Bash bugs before you run anything.
Save yourself the pain
Common mistakes
Oops
Writing for s in $SERVERS, which only loops once over a single joined string.
Do this instead
Use an array and loop with "${SERVERS[@]}", quotes included.
Oops
Building a 500-line Bash script with complex logic and string parsing.
Do this instead
When Bash gets hard to read, move the logic to Python. Keep Bash for gluing commands together.
Your mission
Add flags to a script
Quick check
What does "${SERVERS[@]}" (with quotes) do in a for loop?
Go deeper
- 1Refactor a simple script from Phase 2 to accept command-line arguments properly.
- 2Practice writing a Bash function and calling it from multiple places in a script.
- 3Learn to use `set -e` and `set -u` to make scripts fail loudly instead of silently.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.