How to Return Value From a Bash Function

Bash, one of the most popular shell scripting languages, handles functions a little differently from what you might expect if you're coming from other programming languages. In particular, returning values from Bash functions can be a bit tricky to understand for newcomers.

In this blog post, we’ll start by looking at the difference between Bash functions and functions in other popular programming languages. We’ll then learn how to return values from Bash functions using two methods: by sending function output to standard output, and by leveraging global variables. Let’s dive in!

Prerequisite

To try out the scripts in this blog post, you need access to a Bash shell. You also need a text editor, such as "nano" or "vim", which come pre-installed by default in many Unix-like operating systems.

For the purpose of this blog post, I'll be using KodeKloud’s Ubuntu playground, which lets you access a pre-installed Ubuntu operating system in just one click. Best of all, you won't need to go through the hassle of installing any additional software— everything you need is already set up and ready to use.

Create a Script File

Let’s start by creating a Bash script file named demo.sh. This is where we'll place and run the scripts we're about to write in the upcoming sections. To create it, run the following command:

touch /usr/local/bin/demo.sh

Note: While you're free to create the demo.sh file in any directory of your choice, we're placing it in the /usr/local/bin directory for a specific reason. In most Linux distributions, this directory is included in the system's command path. This means we can run our script without making it executable.

With the script file created, let’s move on to the next section.

Exit Status in Bash Functions

In programming languages like Python or JavaScript, a function can return a value. For example, consider the following Python code:

def add(x, y):
    return x + y

print(add(3, 4))  # outputs: 7

Here, we have a simple function named add, which takes two arguments x and y, and uses the return keyword to return their sum.

In Bash, however, functions don't return values in the same way. Instead, they produce an exit status of the last command that was run within the function. This exit status can be either 0 (indicating success) or a non-zero number (indicating some kind of error).

Bash uses a special variable $? to hold this exit status. Therefore, after the execution of a function, you can check the $? variable to determine the success or failure of the operation.

Let’s demonstrate this with an example. Run the following command to open the demo.sh file using the "nano" text editor:

nano /usr/local/bin/demo.sh

Next, add the following script to the editor:

#!/bin/bash

# Define the function
function demo {
  echo "This is my function"
}

# Call the function
demo

# Check the exit status
echo "The exit status of the demo function is: $?"

This script defines a function called demo. When we invoke this function, it prints the message This is my function to the terminal. Subsequently, we display the exit status of the function.

Since the demo function lacks an explicit return statement, its return value corresponds to the exit status of the last command executed within the function. In this case, the last command is echo "This is my function", which, assuming successful execution, returns an exit status of 0.

Once you've added the script, you'll need to save your work and exit the "nano" editor. To save, press ctrl + o. You'll see a message asking for the File Name to Write. Just press enter to agree with the name that's already there. After your file is saved, you can leave "nano" by pressing ctrl + x.

Now, run the script using the following command:

bash demo.sh

You’ll see the following output:

The first line indicates the message printed by the demo function. The second line states the exit status of the demo function, represented as 0, which confirms that the function was executed successfully.

2 Methods to Return Value From a Bash Function

In the previous section, we learned that Bash functions do not return values in the conventional sense. Rather, they provide an exit status, which may not be directly useful for further processing within the program.

That being said, there are two common methods used to extract return values from a Bash function. Let's explore these methods in detail.

Method-1: Sending Function Output to Standard Output

This method involves leveraging the standard output (stdout) stream. In a Bash function, you can send any output to stdout using the echo or printf commands. This output can then be captured and used in the rest of your script.

This method treats the Bash function more like a standalone script or program, where output is sent to stdout and then captured or redirected as necessary.

Let's demonstrate this with an example. Run the following command to open the demo.sh file using the "nano" text editor:

nano /usr/local/bin/demo.sh

Next, add the following script to the editor:

#!/bin/bash

function demo {
  local greet="Hello World!"
  echo ${greet}
}

# Call the function and capture its output
output=$(demo)
echo ${output}  # Outputs: Hello World!

In the script above, we first define a function named demo. Inside this function, we define a local variable greet and assign it the value Hello World!. We then use the echo command to send the value of the greet variable (which is "Hello World!") to the standard output (stdout).

Next, we invoke the function and capture its output using the $() notation. This essentially executes demo in a subshell and stores the output in a variable called output. This captured output can subsequently be utilized elsewhere within our script.

After you've written the script in the "nano" editor, save your work by pressing ctrl+o. When prompted, confirm the filename by pressing enter. Finally, press ctrl+x to exit the editor.

Now, run the script using the following command:

bash demo.sh

You’ll see the following output:

As you can see, we've successfully obtained a value from the demo function by redirecting the function's output, initially sent to stdout, into our variable output.

Method-2: Leveraging Global Variables

The second method to return values from a Bash function involves the use of global variables. While this approach may not be typical in many programming languages, it can be quite effective in Bash scripting due to the shell's unique handling of variable scope.

By default, all variables in Bash are global, meaning they can be accessed and modified anywhere in your script. To get a value from a function, you can define or modify a global variable within the function. The changed value will then be accessible anywhere else in your script.

Note: You can create a local variable within a function by using the local keyword. Local variables are only visible within the function where they are defined, and they won't interfere with global variables of the same name.

Let’s consider an example. Run the following command to open the demo.sh file using the "nano" text editor:

nano /usr/local/bin/demo.sh

Next, add the following script to the editor:

#!/bin/bash

function add_numbers {
  local num1=$1  # First argument
  local num2=$2  # Second argument

  # Assign the sum to a global variable
  result=$((${num1} + ${num2}))
}

# Call the function with two numbers as arguments
add_numbers 5 7

# Access the global variable
echo "The sum is: ${result}"  # Outputs: The sum is: 12

In the script above, we first define a function called add_numbers. Inside this function, we define two local variables: num1 and num2. These variables are assigned the values of the first and second arguments passed to the function, represented by $1 and $2 respectively.

Following that, we calculate the sum of num1 and num2 and store the result in a global variable called result. This assignment effectively allows the computed sum to be accessible from outside the function.

Next, we call the add_numbers function, passing 5 and 7 as arguments. Consequently, the function calculates their sum and assigns the result to the global variable result.

Finally, using the echo command, we access and display the value of the result variable in the terminal.

After you've written the script in the "nano" editor, save your work by pressing ctrl+o. When prompted, confirm the filename by pressing enter. Finally, press ctrl+x to exit the editor.

Now, run the script using the following command:

bash demo.sh

You’ll see the following output:

As you can see, we were able to access the value of the result variable outside of the local scope of the function itself. This was possible because result is a global variable in our script.

However, it's also important to be aware of potential issues when working with global variables. Since they can be accessed and modified anywhere in your script, they can sometimes lead to unexpected results if not managed properly. For instance, if you accidentally use the same variable name in different parts of your script without intending to share the data, you might overwrite values unintentionally.

Conclusion

In this blog post, we discovered that Bash functions don't return values like functions in traditional programming languages do. Instead, they return exit statuses. We also explored two methods to overcome this limitation.

Firstly, we learned how to capture the function's result outside of its context by printing the desired value to the standard output using the echo command. Secondly, we learned how to use global variables within a Bash function to indirectly return values by storing them for later access outside the function's scope.

Now, you have the tools to utilize Bash functions more effectively and return values despite their inherent limitations.

Looking to build a solid foundation in shell scripting or taking your existing skills to the next level? Check out these courses from KodeKloud:

  • Shell Scripts for Beginners: In this course, you'll dive into the practical world of Linux shell scripting. Regardless of your programming experience, you'll master fundamental scripting concepts such as variables, loops, and control logic. Throughout the course, you'll get plenty of hands-on experience using our comprehensive labs. Not only that, you'll also receive immediate feedback on your scripts, which will help you improve and refine them.
  • Advanced Bash Scripting: In this course, you'll start with fundamentals like variables, functions, and parameter expansions and then dive deeper into streams, input/output redirection, and command-line utilities like awk and sed. You'll master arrays for data manipulation and storage and learn best practices to create robust scripts.