Array
| Since: | All Linux | |
|---|---|---|
| macOS(2001 Cheetah) | ||
| Bash 2.0(1996) |
Bash arrays let you store multiple values under a single variable name. There are two types: indexed arrays, where elements are identified by a numeric index, and associative arrays, where elements are identified by a string key. Associative arrays require Bash 4.0 or later.
Syntax
Define an indexed array by listing elements inside parentheses, separated by spaces.
arr=(element1 element2 element3)
You can also assign elements individually by specifying an index.
arr[0]=element1 arr[1]=element2
To define an associative array, first declare it with declare -A, then assign key-value pairs.
declare -A assoc assoc[key]=value
Reference a specific element with ${arr[index]}. Expand all elements with ${arr[@]} or ${arr[*]}.
${arr[0]} # Element at index 0
${arr[@]} # All elements (each as a separate argument)
${arr[*]} # All elements (as one IFS-joined string)
${#arr[@]} # Number of elements
${!arr[@]} # All indices (keys)
${arr[@]:start:length} # Slice: length elements starting at start
Append elements with +=. Remove an element with unset.
arr+=(new_element) # Append to the end unset arr[index] # Delete the element at the given index
Operation List
| Operation | Syntax | Description |
|---|---|---|
| Define an indexed array | arr=(a b c) | Lists elements inside parentheses, separated by spaces. |
| Assign individually | arr[0]=a | Assigns a value to a specific index. |
| Declare an associative array | declare -A assoc | Declares the variable as an associative array. Requires Bash 4.0 or later. |
| Reference an element | ${arr[0]} | Gets the element at the specified index. |
| Expand all elements | ${arr[@]} | Expands all elements as individual arguments. |
| Get element count | ${#arr[@]} | Returns the number of elements in the array. |
| Get all indices | ${!arr[@]} | Expands all indices (or keys for associative arrays). |
| Append an element | arr+=(d) | Appends an element to the end of the array. |
| Delete an element | unset arr[1] | Removes the element at the specified index. |
| Slice | ${arr[@]:1:2} | Gets 2 elements starting from index 1. |
| Loop | for item in "${arr[@]}" | Processes each element one by one. |
Sample Code
A basic example of defining an indexed array and referencing its elements. A list of members is stored in an array.
members=("user1" "user2" "user3" "user4")
echo ${members[0]}
echo ${members[2]}
echo ${#members[@]}
user1
user3
4
To iterate over all elements, use ${arr[@]} inside double quotes.
list_members.sh
#!/bin/bash
members=("user1" "user2" "user3" "user4" "user5")
for member in "${members[@]}"; do
echo "Member: $member"
done
Run the following command:
bash list_members.sh Member: user1 Member: user2 Member: user3 Member: user4 Member: user5
An example of declaring an associative array with declare -A and mapping user names to their team affiliations.
user_roles.sh
#!/bin/bash
declare -A affiliation
affiliation["user1"]="Team A"
affiliation["user2"]="Team B"
affiliation["user3"]="Team A"
for key in "${!affiliation[@]}"; do
echo "$key => ${affiliation[$key]}"
done
Run the following command:
bash user_roles.sh user3 => Team A user2 => Team B user1 => Team A
Appending and deleting elements. Use += to append and unset to delete.
methods=("method_a" "method_b" "method_c")
methods+=("method_d")
echo ${methods[@]}
unset methods[1]
echo ${methods[@]}
echo ${#methods[@]}
method_a method_b method_c method_d
method_a method_c method_d
3
Use a slice to extract a portion of an array. ${arr[@]:start:length} returns length elements starting from index start.
items=("item_a" "item_b" "item_c" "item_d" "item_e")
echo ${items[@]:1:3}
item_b item_c item_d
task_log.sh
#!/bin/bash
# Task log processing script
declare -A email
email["user1"]="user1@example.com"
email["user2"]="user2@example.com"
email["user3"]="user3@example.com"
email["user4"]="user4@example.com"
email["user5"]="user5@example.com"
tasks=("Setup Environment" "Code Review" "Deploy Application" "Monitor System")
echo "=== Task List ==="
for i in "${!tasks[@]}"; do
echo "[$i] ${tasks[$i]}"
done
echo ""
echo "=== Member Contacts ==="
for name in "${!email[@]}"; do
echo "$name: ${email[$name]}"
done
echo ""
echo "Recent tasks: ${tasks[@]:1:2}"
Overview
Both ${arr[@]} and ${arr[*]} expand all elements, but they behave differently inside double quotes. "${arr[@]}" expands each element as a separate argument, so elements containing spaces are not split. "${arr[*]}" joins all elements into a single string using the IFS separator (a space by default). In loops and function calls, always use "${arr[@]}".
Deleting an element with unset does not reindex the array. If you delete index 1, the remaining indices are 0, 2, 3, ... with a gap. ${#arr[@]} returns the actual element count, which may not equal the highest index. To compact the indices, reassign with arr=("${arr[@]}").
Bash arrays are one-dimensional only — multidimensional arrays are not natively supported. Common workarounds include using naming conventions like matrix_1_2 for multiple variables, or encoding data as delimited strings.
Common Mistakes
Common Mistake 1: Elements with spaces are split without quotes
Omitting double quotes when expanding an array causes the shell to split elements on whitespace, breaking multi-word values into separate arguments.
items=("value one" "value two" "value three")
for t in ${items[@]}; do
echo "$t"
done
value
one
value
two
value
three
Without quotes, ${items[@]} is split on whitespace, producing six tokens instead of three. Wrapping the expansion in double quotes preserves each element as a single unit.
for t in "${items[@]}"; do
echo "$t"
done
value one
value two
value three
Common Mistake 2: Forgetting declare -A for associative arrays
If you use string keys without first declaring the array with declare -A, Bash treats it as an indexed array. String keys are converted to the number 0, so each assignment overwrites the same slot and only the last value survives.
affiliation["user1"]="Team A"
affiliation["user2"]="Team B"
affiliation["user3"]="Team A"
echo ${affiliation[@]}
Team A
Three assignments were made, but only one value remains. Adding declare -A at the top fixes the problem.
declare -A affiliation
affiliation["user1"]="Team A"
affiliation["user2"]="Team B"
affiliation["user3"]="Team A"
echo ${#affiliation[@]}
3
If you find any errors or copyright issues, please contact us.