12

I am using set -e to abort on errors.

But for particular one function I want to ignore error and on error I want return code of the function.

Example:

do_work || true 
 if [ $? -ne 0 ] 
  then
   echo "Error"
  fi  

But it is not work return code is always true due || true

How to get return code on do_work on error ?

2
  • Why don't you disable exit on error just before that call? Commented Oct 22, 2012 at 11:25
  • @Mat ya that will work thanks. But for knowledge purpose is there a way I can capture return code ? Commented Oct 22, 2012 at 11:29

5 Answers 5

12
do_work || {
    status=$?
    echo "Error"
}
Sign up to request clarification or add additional context in comments.

Comments

11

Several of the answers given here are not correct, because they result in a test against a variable that will be un-defined if do_work succeeds.

We need to cover the successful case as well, so the answer is:

set -eu
do_work && status=0 || status=1

The poster's question is a little ambiguous because it says in the text "on error I want return code" but then the code implies "I always want the return code"

To illustrate, here is problematic code:

set -e

do_work() {
    return 0
}

status=123

do_work || status=$?
echo $status

In this code the value printed is 123, and not 0 as we might hope for.

3 Comments

and what about "ignore error" part of the question?
It does exactly what I want: capturing the original exit code while sending a 0 exit code at the end of the command
@jangorecki the "ignore error" part is implicit by using the && (AND operator). Its right-hand operand must be executed in any case (to ensure that both operands are true). If do_work succeeds, then status=0 is executed and the || lazy-evaluation will not execute status=1 If it fails, the && expression fails || will have to run status=1 in order to know if the right-hand operand will make the || expression evaluate to true (given than the first operand evaluated to false (because of failure of first && operand).
8

You could use a subshell shortcut:

( set +e; do_work )
 if [ $? -ne 0 ]
  then
   echo "Error"
  fi

Hope this helps =)

Comments

4

One way is to use a pipe, -e only looks at the right-most result of a pipe:

set -e

do_work | true

retn=${PIPESTATUS[0]}
if (( $retn != 0 ))
then   
    echo "Error $retn"
fi     
echo Ending

I wrote a simple do_work which just did exit 42 and got the following output:

Error 42
Ending

The PIPESTATUS array is maintained by Bash, with each element giving the return code of each part of the pipeline. We need to capture it at once (hence $retn) since it is overwritten at each command.

Of course this might be problematic if your do_work includes a pipe itself.

Comments

1
do_work || status=$?
if [ $status -ne 0 ]
then
    echo "Oh no - Fail whale $status has arrived"
fi

Comments

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.