I have a fake bash function such as this:
has_error() {
true
echo "Ok..."
false
echo "Shouldn't be here!"
}
What I'd like to have happen when I 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 keeps executing after an error has been thrown, and moreover, I can't even detect that an error was thrown. How can I change this? I could put a set -e
at the beginning of the function, but then my whole shell will terminate if an error gets thrown. What I'd like is to simply have it return and set the exit status to 1. I could do it with putting &&
in between the commands, or by suffixing every line with || return 1
, but neither of those are very elegant. What's the proper way to do this?
EDIT:
It seems that I'm not being clear enough, because a lot of the responses seem to suggest that I don't actually know how to perform tests in bash. As I mention above, I am aware that I could manually test each command in my function, and return or handle errors as I wanted. I'm also aware that I can set -e
and cause my shell session to terminate on an error. But what I'm asking is: is there a way to have a function cease to continue execution -- without an explicit test -- if any of the commands within that function return nonzero statuses?
$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script. Follow this answer to receive notifications.
Bash Function Return Bash functions differ from most programming languages when it comes to returning a value from a function. By default, bash returns the exit status of the last executed command in the function's body.
bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.
If your function doesn't need to set any global variables, you can have the function create a subshell in which set -e
is used. The subshell will exit, not the shell in which has_error
is called.
has_error () ( # "(", not "{"
set -e
true
echo "Ok..."
false
echo "Shouldn't be here!"
)
The answer by @chepner helped me, but it is incomplete.
If you want to check function return code, don't put function call inside if
statement, use $?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With