Passing Arrays and Associative Maps Between Functions
Use namerefs and indirect expansion to pass complex data structures into and out of functions safely.
Why Passing Arrays to Functions Is Tricky
In Bash, arrays and associative arrays are not first-class values. When you try to pass an array to a function, you cannot simply use $my_array — that only expands the first element.
Consider this broken attempt:
my_func "${my_array[@]}"The function receives a flat list of words. It has no way to know where one element ends and the next begins, and it completely loses the array structure.
Bash provides two reliable mechanisms to pass complex data structures:
- Namerefs (
declare -n) — a reference to another variable by name (Bash 4.3+) - Indirect expansion (
${!varname[@]}) — access a variable whose name is stored in another variable (older Bash)
This lesson covers both techniques so you can write robust, reusable functions that work with arrays and maps.
Passing an Array by Name Using a Nameref
The cleanest modern approach is the nameref: you pass the name of the array as a string, and inside the function you declare a local variable that is a reference to it.
Key syntax:
declare -n ref="$1"—refis now an alias for whatever variable name was passed as the first argument- You read, iterate, and modify
refexactly as if it were the original array
This avoids copying the entire array and lets the function work with arrays of any size.
#!/usr/bin/env bash
print_array() {
declare -n arr="$1" # nameref: arr -> caller's variable
echo "Array has ${#arr[@]} elements:"
for elem in "${arr[@]}"; do
echo " - $elem"
done
}
fruits=(apple banana cherry)
print_array fruitsAll lessons in this course
- Designing Functions with Local Scope and Return Codes
- Building and Sourcing Reusable Bash Libraries
- Parsing Flags and Arguments with getopts
- Passing Arrays and Associative Maps Between Functions