'How to effectively abort the execution of a Bash script from a function

I was using the "exit 1" statement in my Bash functions to terminate the whole script and it worked fine:

function func()
{
   echo "Goodbye"
   exit 1
}
echo "Function call will abort"
func
echo "This will never be printed"

But then I realized that it doesn't do the work when called like:

res=$(func)

I understand that I created a subshell and "exit 1" aborts that subshell and not the primary one; is there a way to write a function which aborts the whole execution, no matter how it is called?

I just need to get the real return value (echoed by the function).



Solution 1:[1]

You can use set -e which exits if a command exits with a non-zero status:

set -e 
func
set +e

Or grab the return value:

(func) || exit $?

Solution 2:[2]

A child process can't force the parent process to close implicitly. You need to use some kind of signaling mechanism. Options might include a special return value, or perhaps sending some signal with kill, something like

function child() {
    local parent_pid="$1"
    local other="$2"
    ...
    if [[ $failed ]]; then
        kill -QUIT "$parent_pid"
    fi
}

Solution 3:[3]

I guess better is

#!/bin/bash
set -e
trap "exit 1" ERR

myfunc() {
     set -x # OPTIONAL TO SHOW ERROR
     echo "Exit with failure"
     set +x # OPTIONAL
     exit 1
}
echo "BEFORE..."
myvar="$(myfunc)"
echo "AFTER..But not shown"

Solution 4:[4]

But is there a way to write a function which aborts the whole execution, no matter how it is called?

No.

I just need to get the real return value (echoed by the function).

You can

res=$(func)
echo $?

Solution 5:[5]

If you just need top be able to bomb out of your scripts from within a function, you can do:

function die () {
    set -e
    /bin/false
}

then elsewhere, within your functions, instead of using "exit", use "die".

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Daenyth
Solution 3 AmazingAlex
Solution 4 Luca
Solution 5 John