3

I want to completely terminate/exit a bash shell script upon error, but using a function error that lets me display a debug output before termination. Now I have the problem that the exit 1 statement inside the error function will not terminate the shell script if the function's output is captured via backticks or $().

Here is my sample script:

    #!/bin/bash

    function error ()
    {
            echo "An error has occured: $1"
            exit 1
    }
    function do_sth ()
    {
            if [ $1 -eq 0 ]; then
                    error "First param must be greater than 0!"
            else
                    echo "OK!"
            fi
    }

    RESULT=`do_sth 0`

    echo "This line should never be printed"

How can I immediately terminate the script in the error() function?

5 Answers 5

5

The problem with command substitution is, that a subshell is started to execute do_sth. exit 1 then terminates this subshell and not the main bash.

You can work around this by appending || exit $?, which exits with the exit code from the command substitution

RESULT=`do_sth 0` || exit $?

If you want to show the error message, redirect it to stderr

echo "An error has occured: $1" >&2
Sign up to request clarification or add additional context in comments.

1 Comment

Problem with that solution is, that the actual error message generated by the error function will not be printed
1
RESULT=`do_sth 0` || exit $?

then echo "An error has occured: $1" >&2

Comments

0

There's no way to avoid the fact that the subshell cannot make the parent terminate directly: the parent will have to evaluate the value returned from the subshell. A common technique is to trap exit and print an error message in the trap function. Since you are generating the error message in a subshell, you cannot simply assign the message to a variable as otherwise might be done, but you can use the filesystem. Please note that this idea is really silly, and it is much cleaner to simply write error messages to stderr. That's what it is for, and that's why it is inherited by children. Something like:

#!/bin/sh

trap final 0 2 15

# Create a temporary file to store error messages.  This is a terrible
# idea: it would be much better to simply write error messages to stderr,
# but this code is attempting to demonstrate the technique of having the
# parent print the message.  Perhaps it would do better to serve as an example
# of why reporting your children's mistakes is a bad idea.  The children
# should be responsible for reporting their own errors.  Doing so is easy,
# since they inherit file descriptor 2 from their parent.
errmsg=$( mktemp xxxxx )
final() {
    test "$?" = 0 || cat $errmsg
    rm -f $errmsg
} >&2

# Must emphasize one more time that this is a silly idea.  The error 
# function ought to be writing to stderr: eg echo "error: $*" >&2
error() { echo "error: $*" > $errmsg; exit 1; }
do_sth() { 
    if test "$1" -eq 0; then
        error "First param must be greater than 0!"
    else
        echo "OK!"
    fi
}


result=$( do_sth 0 ) || exit 1
echo not printed

Comments

0

It seems the (clever) answer is on another question's top answer by @FatalError, here on so

Comments

0

This should work...

#!/bin/bash

trap "exit 1" 50                                       #exit process after receiving signal 50.

function myerror ()
{
    echo "An error has occured: $1" >&2
}
function do_sth ()
{
    if [ $1 -eq 0 ]; then
        myerror "First param must be greater than 0!"
        kill -50 $(ps --pid $$ -opid=)                 #uncommon signal 50 is used.
    else
        echo "OK!"
    fi
}

RESULT=`do_sth 1`
echo $RESULT

RESULT=`do_sth 0`
echo $RESULT

echo "This line should never be printed"

1 Comment

You can have multiple such signals like 50 used here & thus different exit statuses...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.