How to make bash function return 1 on any error

I have a fake bash function like:

has_error() {
  true
  echo "Ok..."
  false
  echo "Shouldn't be here!"
}

      

What I would like is to run this function and check the error status:

> has_error; echo $?
Ok...
1

      

But what actually happens:

> has_error; echo $?
Ok...
Shouldn't be here!
0

      

The problem is that the function continues to execute after the error, and besides, I can't even detect that the error was thrown. How can I change this? I could put set -e

at the beginning of the function, but then my whole shell will end if an error is thrown. I would like to just return it and set the exit status to 1. I could do this by putting &&

between the commands or the suffix of each line with || return 1

, but none of them are very elegant. What's the correct way to do this?

EDIT:

It seems that I am not clear enough because a lot of the answers seem to be saying that I really don't know how to execute tests in bash. As I mentioned above, I know that I could manually check each command in my function and return or handle errors as I wanted. I also know that I can set -e

and will force my shell session to terminate on error. But my question is, is there a way to terminate the execution of a function - without an explicit test - if any of the commands inside that function return non-zero statuses?

+3


source to share


2 answers


If your function does not need to set any global variables, you can create a subshell function that uses set -e

. The subsell will exit, not the shell it is called in has_error

.



has_error () (    # "(", not "{"
  set -e
  true
  echo "Ok..."
  false
  echo "Shouldn't be here!"
)

      

+10


source


The answer from @chepner helped me, but it's incomplete.

If you want to check the return code of a function, do not put the function call inside a statement if

, use a variable $?

.

randomly_fail() (
  set -e
  echo "Ok..."
  (( $RANDOM % 2 == 0 ))
  echo "I'm lucky"
)

FAILED=0
SUCCESS=0
for (( i = 0; i < 10; i++ )); do
  randomly_fail
  if (( $? != 0 )); then
      (( FAILED += 1 ))
  else
    (( SUCCESS += 1 ))
  fi
done

echo "$SUCCESS success, $FAILED failed"

      



This will output something like

Ok...
I'm lucky
Ok...
I'm lucky
Ok...
I'm lucky
Ok...
Ok...
I'm lucky
Ok...
Ok...
I'm lucky
Ok...
Ok...
Ok...
I'm lucky
6 success, 4 failed

      

+2


source







All Articles