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
functionto define acreateArrayfunction. - Inside this function:
- Use the
-noption to create a nameref to manipulate the array directly. - Use the
localkeyword to ensure the local scope. - Populate the array and store it in the
arrayvariable.
- Use the
- Use
functionagain to define theuseArrayfunction. - Inside this function:
- Use the
localkeyword to declare the array variable locally. - Invoke the
createArray()function by passing the array variable created in the previous step. - Use
declarewith-pto 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
declareto declare an array globally. - Use the
functionkeyword 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
echocommand.
|
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
arrayby specifying the index. For example,echo "${array[0]}".
Using Command Substitution
To return the entire array from a function in Bash:
- Use the
functionto define a function. - Inside the function:
- Declare and initialize an array locally. To ensure the local scope, we used the
localkeyword. - Use the
echocommand 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
functionkeyword to define a function. - Inside the function:
- Declare and initialize an array. To ensure the local scope, we used the
localkeyword. - Use the
echocommand 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
forto loop over all the individual elements. - Use
doto enter into the loop’s body. - In each iteration:
- Use the
echocommand to print the current item on the Bash console.
- Use the
- Use
doneto end theforloop.
|
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.