We will discuss passing arrays as arguments to functions.
Pre-requistites
- Knowing how to declare an array and set its elements
- Knowing how to get the indices of an array
- Knowing how to cycle through an array
- Knowing how to copy an array
- Understanding indirect expansion
Setup
This is the same setup as the previous post
Let’s make a shell script. In your favourite editor type
#!/bin/bash
And save it somewhere as arrays.sh
. Now we need to make it executable as follows:
[ahmed@amayem ~]$ chmod +x ./arrays.sh
[ahmed@amayem ~]$ ./arrays.sh
[ahmed@amayem ~]$
Looks good so far.
Using an array declared in a calling function
First let’s try to access an array that is declared in a calling function:
calledFunction()
{
echo ${callingArray[@]}
}
callingFunction()
{
local callingArray=("zero" "1" "two" "3" "four")
calledFunction
}
callingFunction
Gives us the following:
[ahmed@amayem ~]$ ./arrays.sh
zero 1 two 3 four
Notice that even if the array is declared as local
the children of the calling function have access to it. This is mentioned in the man
pages:
When local is used within a function, it causes the variable name to have a visible scope restricted to that function and its children.
But what about if we want to pass the array as an argument.
Passing the array as a name
Since we have access to the array of a parent function, there is no need to send more than the array name. Once we have the name of the array we can do whatever we want, including make a copy of it and using it as we wish. We can even use indirection, explained here to modify the original array:
calledFunction()
{
local -a 'arraykeys=("${!'"$1"'[@]}")' copy
arraykeysString=${arraykeys[*]}
for index in $arraykeysString;
do
current=$1"[$index]"
echo ${!current}
copy[$index]=${!current}
done
echo ${copy[*]}
}
callingFunction()
{
local callingArray=("zero" "1" "two" "3" "four")
calledFunction callingArray
}
callingFunction
Gives me:
[ahmed@amayem ~]$ ./arrays.sh
zero
1
two
3
four
zero 1 two 3 four
Passing the array as a reference and indirection
It may be tempting to think of arrays as pointers to the first element of an array as in c
, but that is not the case as we found out when we tried to copy an array by making it equal to the first element of an array. When you pass the name of an array as variable, all you are sending is the name of the array. Hence, sticking [2]
after the parameter does not produce the desired result. Instead we would need to use indirection, which is explained here
References
- Bash
man
pages.