<aside> 🗂️
Module 10 — Arrays and Associative Arrays. Lists of hosts, maps of service→port — how bash stores collections, and how to loop over them without the quoting bugs that plague naive scripts.
🧠 concept → 🧩 analogy → 🧪 exercise → ✅ expected result (hidden) → 🎯 interview questions (hidden)
</aside>
<aside> 📋
Before you start. You need Modules 1–9 — above all "$@" vs "$*" (Module 7: arrays reuse that exact distinction), loops (Module 6), and ${ } expansions (Module 9 — array syntax lives in the same workshop). Arrays are bash-only: none of this works under #!/bin/sh (Module 1 C2's dialect line, drawn again). Tools: nothing new.
</aside>
<aside> 📖
Official docs: Bash manual — Arrays
</aside>
An indexed array is one variable holding an ordered list of values, numbered from 0:
hosts=(web-1 web-2 "db primary" cache-1) # parentheses, space-separated; quote spacey members
echo "${hosts[0]}" # one element, by number
echo "${#hosts[@]}" # how many elements (the # is Module 9's length, applied to the collection)
echo "${!hosts[@]}" # the indexes themselves (0 1 2 3)
Every access wears ${ } braces — $hosts[0] without them is $hosts (which quietly means element 0!) followed by literal text [0], a Module-2-style greedy-parse trap. And notice the third member: "db primary" went in as one element, spaces and all — arrays hold values, not words, which is the entire reason they exist and the subject of A2.
<aside> 🧩
Real-world analogy — the numbered pigeonholes. An indexed array is a wall of numbered pigeonholes behind a reception desk: one label (the variable name), many slots, each slot holding one item intact — even an envelope with a long messy address occupies exactly one slot. The register asks: what's in slot 0? how many slots are used? which slot numbers are in use?
Where the analogy stops working. Pigeonhole walls are dense — slots 0 to N, no gaps. Bash arrays can be sparse: removing slot 1 leaves 0, 2, 3 — the numbering does not close up (A3 demonstrates, and it surprises everyone). "How many" and "up to what number" are different questions in bash.
</aside>
🧪 Exercise 10.1 — the pigeonhole wall
hosts=(web-1 web-2 "db primary" cache-1)
echo "first: ${hosts[0]}"
echo "count: ${#hosts[@]}"
echo "indexes: ${!hosts[@]}"
"${arr[@]}" — the only correct way to say "all of them"<aside> 📖
Official docs: Bash manual — Arrays
</aside>
Expanding a whole array replays Module 7's finale, note for note. "${arr[@]}" (quoted, @) → one word per element, boundaries intact — the faithful forward. "${arr[*]}" (quoted, *) → all elements welded into a single word — the log-line form. Unquoted either way → elements re-split on spaces, the collection's boundaries destroyed. The rule is the same reflex with brackets on: iterating or forwarding → "${arr[@]}"; building one display string → "${arr[*]}"; unquoted → never. It is not a coincidence: $@/$* are this mechanism — the positional parameters are simply bash's oldest array.
🧪 Exercise 10.2 — the probe settles it again
The third probe mangles on purpose.
hosts=(web-1 web-2 "db primary" cache-1)
printf '[%s]\n' "${hosts[@]}"
echo "---"
printf '[%s]\n' "${hosts[*]}"
echo "---"
printf '[%s]\n' ${hosts[@]} # ← unquoted: boundaries destroyed