Bash Arrays 4: Passing Arrays as Function Arguments/Parameters

We will discuss passing arrays as arguments to functions.

Pre-requistites

  1. Knowing how to declare an array and set its elements
  2. Knowing how to get the indices of an array
  3. Knowing how to cycle through an array
  4. Knowing how to copy an array
  5. 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

  1. Bash man pages.

Ahmed Amayem has written 90 articles

A Web Application Developer Entrepreneur.

  • Valdemar Nebonyr

    you are the good teacher!