11

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?
    – Mat
    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 ?
    – Vivek Goel
    Commented Oct 22, 2012 at 11:29

5 Answers 5

12
do_work || {
    status=$?
    echo "Error"
}
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
  • and what about "ignore error" part of the question?
    – jangorecki
    Commented Mar 18, 2019 at 13:53
  • It does exactly what I want: capturing the original exit code while sending a 0 exit code at the end of the command
    – Yujin Kim
    Commented Oct 2, 2019 at 11:30
  • @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). Commented Oct 31, 2022 at 8:47
8

You could use a subshell shortcut:

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

Hope this helps =)

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.

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.