Reputation: 21
Why does the following script gives different outputs, when the same expression is evaluated with and without test
? What rules are to be taken into account: operator precedence, left-to-right or right-to-left argument evaluation ...? In my opinion it is important to understand the logic of bash at this basic level.
function a()
{
local r=1
printf "a%d" $r
return $r
}
function b()
{
local r=1
printf "b%d" $r
return $r
}
function c()
{
local r=1
printf "c%d" $r
return $r
}
printf "$BASH_VERSION\n" #outputs 4.3.48(1)-release
a || b && c #outputs a1b1
printf "\n"
test a || b && c #outputs c1
printf "\n"
Upvotes: 2
Views: 278
Reputation: 85580
Your usage of test
is incorrect in this context. test
sets the return code to the calling shell by evaluating an expression. The way you've used it, test a
does not evaluate to an expression but ends up setting a code as test 1
which does a string check and always asserts a code 0 (success error code). See
test 0; echo $?
0
test 1; echo $?
0
test false; echo $?
0
test true; echo $?
0
test
evaluates the expression a||b
which sets up a return code 1
to test
which returns a success error code and runs the function c
which prints the value you are seeing.
For cases of simplicity, I've changed the function calls to use command false
which returns error code 1
to the shell as your function.
bash -cx "test false || false && echo hi"
+ test false
+ echo hi
hi
As you can see, the moment test false|| false
is run, the command sets success code to the shell and with the operand &&
the echo
command is run.
For checking the error code from the function, perhaps you should have checked as
test a != "0"
Upvotes: 1
Reputation: 85767
That's because
a
runs a
whereas
test a
runs test
, passing a
as an argument. They're completely different commands.
Similarly,
pwd
runs pwd
, but
echo pwd
runs echo
, passing pwd
as an argument.
X || Y
is not an expression, it's a compound command that first runs the X
subcommand and then (if its exit status is non-zero) runs Y
.
See https://www.gnu.org/software/bash/manual/bashref.html#Lists for details.
Upvotes: 1