Associative Arrays
Indexed arrays answer “what is item number 0?” Associative arrays answer “what value belongs to this key?” They are useful for small lookup tables, configuration maps, counters, and metadata when Bash remains the right abstraction level.
Learning objectives
By the end of this lesson
- Declare associative arrays.
- Assign and retrieve key-value pairs.
- Check whether keys exist.
- Iterate over keys and values.
- Use maps without confusing missing and empty values.
1. Associative arrays require explicit declaration
declare -A ports
ports[api]=8080
ports[worker]=9090
ports[metrics]=9100
printf 'api port=%s\n' "${ports[api]}"Unlike indexed arrays, associative keys are strings. Always use declare -A before assignment.
2. Compound assignment can initialize a map
declare -A images=(
[api]="registry.example/api:2.0"
[worker]="registry.example/worker:2.0"
[cache]="redis:7"
)
printf '%s\n' "${images[worker]}"3. ${!map[@]} expands the keys
for service in "${!images[@]}"; do
printf 'service=%s image=%s\n' \
"$service" "${images[$service]}"
doneDo not treat associative-array iteration order as a stable business interface. If order matters, sort the keys or maintain a separate ordered array.
4. Check key existence separately from value emptiness
declare -A config
config[region]=""
config[environment]="staging"
if [[ -v 'config[region]' ]]; then
printf 'region key exists, value=<%s>\n' "${config[region]}"
fi
if [[ ! -v 'config[missing]' ]]; then
printf 'missing key does not exist\n'
fiAn existing key can intentionally hold an empty string. That differs from an absent key.
5. Parameter expansion can supply missing-value defaults
declare -A config=(
[environment]="staging"
)
region=${config[region]:-eu-central-1}
printf 'region=%s\n' "$region"Remember that the :- form treats both missing and empty values as needing the default. Use the no-colon form when empty must remain meaningful.
6. unset removes a key
declare -A state=(
[api]="ready"
[worker]="ready"
[cache]="degraded"
)
unset 'state[cache]'
printf 'keys: %s\n' "${!state[@]}"7. Associative arrays can implement small counters
declare -A failures=()
for service in api api worker api; do
(( failures["$service"] += 1 ))
done
for service in "${!failures[@]}"; do
printf '%s failures=%d\n' "$service" "${failures[$service]}"
doneThis is useful for lightweight aggregation, but large datasets or complex grouping usually belong in awk, Python, or another data-processing tool.
8. Maps are useful for translating symbolic names
declare -A contexts=(
[dev]="cluster-dev"
[staging]="cluster-stg"
[prod]="cluster-prod"
)
environment=${1:-staging}
if [[ ! -v 'contexts[$environment]' ]]; then
printf 'unsupported environment: %s\n' "$environment" >&2
exit 65
fi
context=${contexts[$environment]}
printf 'context=%s\n' "$context"9. Associative arrays are not nested object graphs
A Bash associative array maps one string key to one string value. It does not natively store nested dictionaries, typed objects, or JSON-like trees.
declare -A service_meta
service_meta[api.image]="api:2.0"
service_meta[api.port]="8080"Flattened keys such as api.image can work for tiny maps, but deep structured state is a strong sign that JSON plus jq, Python, or another language is a better fit.
10. Do not invent an ad-hoc map serialization casually
Joining keys and values with commas, colons, or spaces becomes ambiguous as soon as data can contain those characters. If the map must cross a process or storage boundary, use a real format such as JSON, env-style key-value data with a strict contract, or a purpose-built file format.
11. Hands-on lab: environment-to-cluster lookup
mkdir -p "$HOME/devops-academy/bash/chapter07/lesson02"
cd "$HOME/devops-academy/bash/chapter07/lesson02"
cat > lookup.sh <<'EOF'
#!/usr/bin/env bash
declare -A cluster=(
[dev]="dev-cluster"
[staging]="staging-cluster"
[prod]="prod-cluster"
)
declare -A namespace=(
[dev]="sandbox"
[staging]="preprod"
[prod]="production"
)
environment=${1:-}
if [[ ! -v 'cluster[$environment]' ]]; then
printf 'unknown environment: %s\n' "$environment" >&2
exit 65
fi
printf 'environment=%s\n' "$environment"
printf 'cluster=%s\n' "${cluster[$environment]}"
printf 'namespace=%s\n' "${namespace[$environment]}"
EOF
bash lookup.sh staging
bash lookup.sh prod
bash lookup.sh qa || trueVerification checklist
12. Knowledge check
Question 1. How do you declare an associative array?
declare -A name.Question 2. How do you expand all keys?
${!name[@]}.Question 3. Why is checking key existence different from checking for a non-empty value?
Question 4. Are associative arrays a good representation for deeply nested JSON-like data?
13. Summary
Associative arrays provide small key-value maps inside Bash. They are excellent for configuration lookups, labels, counters, and simple metadata, provided you keep ordering and structural limitations in mind.
14. Further reading
- GNU Bash Reference Manual — Arrays.
- GNU Bash Reference Manual — Bash Conditional Expressions:
-v. - GNU Bash Reference Manual — Arithmetic Evaluation.
- ShellCheck documentation — associative-array usage.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this address.