bashfunctionexitsubshell

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

  • What you could do, is register the top level shell for the TERM signal to exit, and then send a TERM to the top level shell:

    #!/bin/bash
    trap "exit 1" TERM
    export TOP_PID=$$
    
    function func()
    {
       echo "Goodbye"
       kill -s TERM $TOP_PID
    }
    
    echo "Function call will abort"
    echo $(func)
    echo "This will never be printed"
    

    So, your function sends a TERM signal back to the top level shell, which is caught and handled using the provided command, in this case, "exit 1".