Mircea Ispas
Mircea Ispas

Reputation: 20780

How to terminate bash function execution

I have several functions in my .bashrc and I want to terminate the whole "run" on error. For example:

function assert_env()
{
    var_name=$1

    if [ -z "${!var_name}" ]; then
        printf "Missing environment variable: $var_name\n"
        exit 1
    fi
}

function my_test()
{
    assert_env "abc"
    print $abc
}

If i type my_test in terminal I want to terminate the execution, but this script closes the terminal (as expected - I run exit 1).

How may I terminate the execution without closing the current terminal?

EDIT: To be more specific - I don't want to return from assert_env, I want my following commands from my_test to not be executed if the condition from assert_env is not met, something like C++ assert

Upvotes: 2

Views: 134

Answers (2)

Mircea Ispas
Mircea Ispas

Reputation: 20780

I've found a workaround - execute the function content in a subshell

Example:

function assert_env()
{
    var_name=$1

    if [ -z "${!var_name}" ]; then
        printf "Missing environment variable: $var_name\n"
        exit 1
    fi
}

function my_test()
{
(
    printf "$1\n"

    assert_env "abc"

    printf $abc
)
}

Upvotes: 0

Inian
Inian

Reputation: 85530

Note that exit returns the exit code specified to the shell itself, so using exit 1 would obviously exit your current shell. You need to use return here.

As far as you requirement is considered, just use the exit code from the function assert_env to decide if you want to run further statements. Here using return will cause the current function to go out of scope and what ever code you are returning back to the callee can be used to check if its successful/failure

function assert_env() {
    local ret_val=0; var_name=$1  

    if [ -z "${!var_name}" ]; then
        printf "Missing environment variable: $var_name\n"
        ret_val=1
    fi

    return ${ret_val}
}

Now using it

function my_test() {
    if ! assert_env "abc"; then
        return
    fi
    # Or could be just written as assert_env "abc" || return
}

This way, if the assert_env returns 0, the if-clause in my_test asserts failure and rest of the code gets executed. And on returning 1 the condition becomes true and the function call is returned without exiting the main scipt.

Note that function keyword is non-standard and not POSIX compliant and may not work across shells. Just drop the keyword if you want to make it portable.

Upvotes: 1

Related Questions