Build the mental model
A regular bash array is an ordered list of values you access by numeric index, much like arrays in other languages, and it lets you group related data — such as a list of filenames or usernames — into a single variable instead of juggling a growing set of separate ones like file1, file2, file3. Indexed arrays start at position 0, grow automatically when you append to them with the += operator, and expose two companion expansions that go together: ${arr[@]}, which expands to every element as separate words, and ${#arr[@]}, which gives you the element count without having to loop and count manually. Bash 4 and later add a second array type: associative arrays, declared explicitly with declare -A, which map your own string keys to values instead of relying on sequential numbers. That explicit declaration matters — bash needs to know in advance that a variable is an associative array so it can parse prices[apple]=1 as a key lookup rather than trying to evaluate apple as an arithmetic index the way it would for an indexed array. One subtlety worth internalizing early: unlike an indexed array's natural numeric order, an associative array's keys have no guaranteed iteration order, so any script that needs predictable, repeatable output — like a report or a diff-friendly log — has to explicitly sort the keys before looping over them, exactly as ${!prices[@]} is piped through sort in this lesson's code.
Connect it to a real scenario
Imagine writing a deployment script that needs to back up a fixed set of directories, or a monitoring script that maps server names to their IP addresses — these two shapes of problem map directly onto bash's two array types. For the directory list, you'd store paths in an indexed array exactly like fruits=(apple banana cherry) in the code, then loop over "${fruits[@]}" so each directory is backed up with the same logic instead of being hardcoded three separate times; adding a fourth directory later means adding one line to the array, not duplicating a whole block of script. For the server-to-IP mapping, an indexed array would force you to remember that index 0 means 'web-server' and index 1 means 'db-server' — fragile and unreadable. An associative array like prices in the code solves this directly: declare -A prices, then prices[apple]=1 lets you look up a value by a meaningful name with ${prices[banana]} instead of a position you'd have to memorize. And because associative array key order is not guaranteed, the script deliberately captures the keys with ${!prices[@]}, pipes them through tr and sort, and only then loops — a pattern worth reusing anytime you build a report or log from an associative array and need the output to be the same every time you run it.
Try the working example
#!/bin/bash
# Indexed array: an ordered list of values
fruits=(apple banana cherry)
echo "First fruit: ${fruits[0]}"
echo "All fruits: ${fruits[@]}"
echo "Number of fruits: ${#fruits[@]}"
# Append a new element
fruits+=(date)
echo "After append: ${fruits[@]}"
# Loop over every element
for fruit in "${fruits[@]}"; do
echo "I like $fruit"
done
# Associative array (bash 4+): key-value pairs
declare -A prices
prices[apple]=1
prices[banana]=2
prices[cherry]=3
echo "Price of banana: ${prices[banana]}"
# Sort keys before looping so output order is predictable
for key in $(echo "${!prices[@]}" | tr ' ' '\n' | sort); do
echo "$key costs ${prices[$key]}"
doneRunning this script prints:
First fruit: apple
All fruits: apple banana cherry
Number of fruits: 3
After append: apple banana cherry date
I like apple
I like banana
I like cherry
I like date
Price of banana: 2
apple costs 1
banana costs 2
cherry costs 35-minute try-it
Create an indexed array of three of your favorite programming languages, print the total count, then write an associative array that maps each language to the year it first appeared, and print one of those pairs.
One important caution
Forgetting to quote "${arr[@]}" in a for loop, which causes elements containing spaces to be split into multiple words
Confusing ${arr[@]} (all elements) with ${arr[*]} or with the plain unindexed $arr, which only refers to the first element
GNU Bash Manual: Arrays — Bash / Shell Scripting