Table of Contents
Bash cannot return values, whether a single value or an array, but it can return a status (the same as other programs). However, there are multiple turnarounds that we can use to return an array from a function. Let’s explore them below.
Using nameref
Feature
To return the entire array from a function in Bash:
- Use the
function
to define acreateArray
function. - Inside this function:
- Use the
-n
option to create a nameref to manipulate the array directly. - Use the
local
keyword to ensure the local scope. - Populate the array and store it in the
array
variable.
- Use the
- Use
function
again to define theuseArray
function. - Inside this function:
- Use the
local
keyword to declare the array variable locally. - Invoke the
createArray()
function by passing the array variable created in the previous step. - Use
declare
with-p
to print the declaration of the array variable (created in the third last step) on the console.
- Use the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#!/bin/bash createArray() { local -n array=$1 array=(1 2 3 4) } useArray() { local testArray createArray TestArray declare -p TestArray } useArray |
1 2 3 |
declare -a TestArray=([0]="1" [1]="2" [2]="3" [3]="4") |
In Bash, nameref
is a feature that allows us to create a reference to a variable using a different name. It is a form of indirection where the reference variable acts as an alias for the original variable. Any changes to the reference variable will affect the original variable and vice versa.
In our case, the reference variable was the array
from the createArray
function, while the original variable was the testArray
from the useArray
function. We used the nameref
to indirectly manipulate variables without using complex workarounds. You can find more details here.
Using Global Variable
To get an array from a function in Bash:
- Use
declare
to declare an array globally. - Use the
function
keyword to define the specified function; you can name this function whatever you want. - Inside the function created in the previous step:
- Initialize the array that we declared globally in the first step.
- Call the function created in the second step.
- Finally, print the entire array using the
echo
command.
1 2 3 4 5 6 7 8 9 10 |
#!/bin/bash declare -a array function return_array(){ array=("This" "is" "a" "sample" "line") } return_array echo "${array[@]}" |
1 2 3 |
This is a sample line |
We used the declare
keyword to declare an empty array that we named array
; here, the -a
option indicated the array
was an indexed array. Next, we used the function
keyword to define the return_array
function. This function populated the array
with the specified string values.
After invoking the return_array
function, we used the echo
command with parameter expansion syntax (${array[@]}
) to print the entire array. Here, parameter expansion syntax was used to expand all items of the array
variable, while the [@]
notation signified that we wanted to expand all items as individual words.
You can also access the individual elements of the
array
by specifying the index. For example,echo "${array[0]}"
.
Using Command Substitution
To return the entire array from a function in Bash:
- Use the
function
to define a function. - Inside the function:
- Declare and initialize an array locally. To ensure the local scope, we used the
local
keyword. - Use the
echo
command to print the whole array.
- Declare and initialize an array locally. To ensure the local scope, we used the
- Call the function created in the first step and capture its output using substitution syntax (
$(...)
). - Print the captured output (in the previous step) on the Bash console using the’ echo’ command.
1 2 3 4 5 6 7 8 9 |
#!/bin/bash function return_array(){ local array=(1 2 3 4 5) echo "${array[@]}" } echo $(return_array) |
1 2 3 |
1 2 3 4 5 |
This example is similar to what we learned in the previous section. Here, inside the return_array
function, we created and initialized an array
. However, we used the local
keyword to ensure that the array
variable is scoped within the return_array
function and not accessible out of it.
After that, we used the echo
command with parameter expansion syntax as echo "${array[@]}"
to print the entire array. Next, we called the function and captured its output using substitution syntax represented by $(...)
, which was further used with echo
to display on the console.
We have learned the parameter expansion syntax in the previous section; you can refer to that.
Using the above script, we can not access the array elements one at a time using index notation until we specify it in the echo
command within the return_array
function. See the following example.
1 2 3 4 5 6 7 8 9 |
#!/bin/bash function return_array(){ local array=(1 2 3 4 5) echo "${array[3]}" } echo $(return_array) |
1 2 3 |
4 |
Until now, we have learned two ways to get the entire array as a string. How to know if the returned array was a string? You can check it using the declare -p
command.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#!/bin/bash declare -a array function return_array1(){ array=("This" "is" "a" "sample" "line") } return_array1 array1="${array[@]}" declare -p array1 function return_array2(){ local array=(1 2 3 4 5) echo "${array[@]}" } array2=$(return_array2) declare -p array2 |
1 2 3 4 |
declare -- array1="This is a sample line" declare -- array2="1 2 3 4 5" |
See, the array1
and array2
were returned as a string value. What if we want to get one element at a time rather than a complete array as a string? This is where the IFS
variable comes into the picture. Let’s explore it below.
Further reading:
Using IFS
Variable
To return the array from a function in Bash:
- Use the
function
keyword to define a function. - Inside the function:
- Declare and initialize an array. To ensure the local scope, we used the
local
keyword. - Use the
echo
command to print the entire array.
- Declare and initialize an array. To ensure the local scope, we used the
- Call the function created in the first step, and capture its output in a variable.
- Enclose the variable (created in the previous step) within parentheses to split it into individual elements and assign them to a variable.
- Use the
for
to loop over all the individual elements. - Use
do
to enter into the loop’s body. - In each iteration:
- Use the
echo
command to print the current item on the Bash console.
- Use the
- Use
done
to end thefor
loop.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#!/bin/bash function return_array(){ local array=(1 2 3 4 5) echo "${array[@]}" } IFS=' ' entire_array=$(return_array) individual_elements=($entire_array) for i in "${!individual_elements[@]}"; do echo "Element at index $i: ${individual_elements[$i]}" done |
1 2 3 4 5 6 7 |
Element at index 0: 1 Element at index 1: 2 Element at index 2: 3 Element at index 3: 4 Element at index 4: 5 |
In the last section, we have already learned about the return_array
function and local array creation. Here, after the function, we set the value of the IFS
(Internal Field Separator) variable to a single space character. This line (IFS=' '
) determined how the elements in a string would split when assigned to an array.
Then, we invoked the return_array
function and grabbed its output as a string using substitution syntax ($(...)
), which we stored in the entire_array
variable. Then, moving forward, we enclosed the entire_array
within the parentheses to split $entire_array
into individual items based on the specified IFS
value (which was a space character in this case).
After splitting, we stored them in the individual_elements
variable. Finally, we used the for
loop to iterate over the individual_elements
and printed the current item on each iteration using the echo
command. Note that the ${!individual_elements[@]}
notation expanded to all indices of an array, while ${individual_elements[$i]}
was used to access the current item; here, the value of $i
varied based on the iteration.
That’s all about how to return array from Function in Bash.