I thought I know the shell, but I got bitten with unexpected behavior.
Consider this code:
#!/bin/bash
foo()
{
if false
then
echo success
else
return
fi
}
foo || echo failure
Now at first glance one would think the else return
part is superfluous, but it is not. The code as it is outputs failure
, but when the cited part is removed, then nothing is output.
The bash manual explains (for if
):
The exit status is the exit status of the last command executed, or zero if no condition tested true.
Somehow I'd expect the if
to fail when the command had failed.
Imagine where echo success
stands there are actually dependent commands that make only sense to execute when the main command (false
here) succeeded.
What is the logic behind that unexpected behavior?
Seen for bash-4.4. Related: https://stackoverflow.com/a/63884458/6607497
CodePudding user response:
The if
statement never actually completes with the return
statement; the function returns immediately, with the exit status provided by return
. That exit status is the status of the last command prior to return
to exit, which was false
.
Without the return
, the if
does complete, and as documented, the exit status of an if
command is defined to be 0 if none of the conditions in the if
clause or any elif
clause evaluated to true. This makes sense, because the if
statement successfully determined that none of the if
or elif
blocks needed to be executed.
CodePudding user response:
The bash manual explains (for return
):
return
return [n]
Cause a shell function to stop executing and return the value n to its caller. If n is not supplied, the return value is the exit status of the last command executed in the function.
So:
if false
then
echo success
else
# The LAST command is `false` with exit status 1 !
return # Returns 1 - returns failure!
fi