[bash] Difference between return and exit in Bash functions

What is the difference between the return and exit statement in Bash functions with respect to exit codes?

This question is related to bash function return-value return exit

The answer is


The OP's question: What is the difference between the return and exit statement in BASH functions with respect to exit codes?

Firstly, some clarification is required:

  • A (return|exit) statement is not required to terminate execution of a (function|shell). A (function|shell) will terminate when it reaches the end of its code list, even with no (return|exit) statement.

  • A (return|exit) statement is not required to pass a value back from a terminated (function|shell). Every process has a built-in variable $? which always has a numeric value. It is a special variable that cannot be set like "?=1", but it is set only in special ways (see below *).

    The value of $? after the last command to be executed in the (called function | sub shell) is the value that is passed back to the (function caller | parent shell). That is true whether the last command executed is ("return [n]"| "exit [n]") or plain ("return" or something else which happens to be the last command in the called function's code.

In the above bullet list, choose from "(x|y)" either always the first item or always the second item to get statements about functions and return, or shells and exit, respectively.

What is clear is that they both share common usage of the special variable $? to pass values upwards after they terminate.

* Now for the special ways that $? can be set:

  • When a called function terminates and returns to its caller then $? in the caller will be equal to the final value of $? in the terminated function.
  • When a parent shell implicitly or explicitly waits on a single sub shell and is released by termination of that sub shell, then $? in the parent shell will be equal to the final value of $? in the terminated sub shell.
  • Some built-in functions can modify $? depending upon their result. But some don't.
  • Built-in functions "return" and "exit", when followed by a numerical argument both $? with argument, and terminate execution.

It is worth noting that $? can be assigned a value by calling exit in a sub shell, like this:

# (exit 259)
# echo $?
3

Sometimes, you run a script using . or source.

. a.sh

If you include an exit in the a.sh, it will not just terminate the script, but end your shell session.

If you include a return in the a.sh, it simply stops processing the script.


I don't think anyone has really fully answered the question because they don't describe how the two are used. OK, I think we know that exit kills the script, wherever it is called and you can assign a status to it as well such as exit or exit 0 or exit 7 and so forth. This can be used to determine how the script was forced to stop if called by another script, etc. Enough on exit.

return, when called, will return the value specified to indicate the function's behavior, usually a 1 or a 0. For example:

    #!/bin/bash
    isdirectory() {
      if [ -d "$1" ]
      then
        return 0
      else
        return 1
      fi
    echo "you will not see anything after the return like this text"
    }

Check like this:

    if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi

Or like this:

    isdirectory || echo "not a directory"

In this example, the test can be used to indicate if the directory was found. Notice that anything after the return will not be executed in the function. 0 is true, but false is 1 in the shell, different from other programming languages.

For more information on functions: Returning Values from Bash Functions

Note: The isdirectory function is for instructional purposes only. This should not be how you perform such an option in a real script.*


Remember, functions are internal to a script and normally return from whence they were called by using the return statement. Calling an external script is another matter entirely, and scripts usually terminate with an exit statement.

The difference "between the return and exit statement in Bash functions with respect to exit codes" is very small. Both return a status, not values per se. A status of zero indicates success, while any other status (1 to 255) indicates a failure. The return statement will return to the script from where it was called, while the exit statement will end the entire script from wherever it is encountered.

return 0  # Returns to where the function was called.  $? contains 0 (success).

return 1  # Returns to where the function was called.  $? contains 1 (failure).

exit 0  # Exits the script completely.  $? contains 0 (success).

exit 1  # Exits the script completely.  $? contains 1 (failure).

If your function simply ends without a return statement, the status of the last command executed is returned as the status code (and will be placed in $?).

Remember, return and exit give back a status code from 0 to 255, available in $?. You cannot stuff anything else into a status code (e.g., return "cat"); it will not work. But, a script can pass back 255 different reasons for failure by using status codes.

You can set variables contained in the calling script, or echo results in the function and use command substitution in the calling script; but the purpose of return and exit are to pass status codes, not values or computation results as one might expect in a programming language like C.


First of all, return is a keyword and exit is a function.

That said, here's a simplest of explanations.

return

It returns a value from a function.

exit

It exits out of or abandons the current shell.


Adding an actionable aspect to a few of the other answers:

Both can give exit codes - default or defined by the function, and the only 'default' is zero for success for both exit and return. Any status can have a custom number 0-255, including for success.

Return is used often for interactive scripts that run in the current shell, called with . script.sh for example, and just returns you to your calling shell. The return code is then accessible to the calling shell - $? gives you the defined return status. Exit in this case also closes your shell (including SSH connections, if that's how you're working).

Exit is necessary if the script is executable and called from another script or shell and runs in a subshell. The exit codes then are accessible to the calling shell - return would give an error in this case.


In simple words (mainly for newbie in coding), we can say,

    `return`: exits the function,
    `exit()`: exits the program (called as process while running)

Also if you observed, this is very basic, but...,

    `return`: is the keyword
    `exit()`: is the function

return will cause the current function to go out of scope, while exit will cause the script to end at the point where it is called. Here is a sample program to help explain this:

#!/bin/bash

retfunc()
{
    echo "this is retfunc()"
    return 1
}

exitfunc()
{
    echo "this is exitfunc()"
    exit 1
}

retfunc
echo "We are still here"
exitfunc
echo "We will never see this"

Output

$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()

  • exit terminates the current process; with or without an exit code, consider this a system more than a program function. Note that when sourcing, exit will end the shell. However, when running, it will just exit the script.

  • return from a function go back to the instruction after the call, with or without a return code. return is optional and it's implicit at the end of the function. return can only be used inside a function.

I want to add that while being sourced, it's not easy to exit the script from within a function without killing the shell. I think, an example is better on a 'test' script:

#!/bin/bash
function die(){
   echo ${1:=Something terrible wrong happen}
   #... clean your trash
   exit 1
}

[ -f /whatever/ ] || die "whatever is not available"
# Now we can proceed
echo "continue"

doing the following:

user$ ./test
Whatever is not available
user$

test -and- the shell will close.

user$ . ./test
Whatever is not available

Only test will finish and the prompt will show.

The solution is to enclose the potentially procedure in ( and ):

#!/bin/bash
function die(){
   echo $(1:=Something terrible wrong happen)
   #... Clean your trash
   exit 1
}

( # Added        
    [ -f /whatever/ ] || die "whatever is not available"
    # Now we can proceed
    echo "continue"
) # Added

Now, in both cases only test will exit.


If you convert a Bash script into a function, you typically replace exit N with return N. The code that calls the function will treat the return value the same as it would an exit code from a subprocess.

Using exit inside the function will force the entire script to end.


Examples related to bash

Comparing a variable with a string python not working when redirecting from bash script Zipping a file in bash fails How do I prevent Conda from activating the base environment by default? Get first line of a shell command's output Fixing a systemd service 203/EXEC failure (no such file or directory) /bin/sh: apt-get: not found VSCode Change Default Terminal Run bash command on jenkins pipeline How to check if the docker engine and a docker container are running? How to switch Python versions in Terminal?

Examples related to function

$http.get(...).success is not a function Function to calculate R2 (R-squared) in R How to Call a Function inside a Render in React/Jsx How does Python return multiple values from a function? Default optional parameter in Swift function How to have multiple conditions for one if statement in python Uncaught TypeError: .indexOf is not a function Proper use of const for defining functions in JavaScript Run php function on button click includes() not working in all browsers

Examples related to return-value

Multiple values in single-value context MySQL stored procedure return value Best way to return a value from a python script How to return a value from try, catch, and finally? Return value in a Bash function How to return a string from a C++ function? Efficient way to return a std::vector in c++ Return value from a VBScript function store return value of a Python script in a bash script How can I return two values from a function in Python?

Examples related to return

Method Call Chaining; returning a pointer vs a reference? How does Python return multiple values from a function? Return multiple values from a function in swift Python Function to test ping Returning string from C function "Missing return statement" within if / for / while Difference between return 1, return 0, return -1 and exit? C# compiler error: "not all code paths return a value" How to return a struct from a function in C++? Print raw string from variable? (not getting the answers)

Examples related to exit

Ruby - ignore "exit" in code Difference between return 1, return 0, return -1 and exit? Android: Quit application when press back button How to exit a function in bash break/exit script How to use sys.exit() in Python exit application when click button - iOS How to properly exit a C# application? What is the command to exit a Console application in C#? Get exit code for command in bash/ksh