[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Possible bug in bash

From: Robert Elz
Subject: Re: Possible bug in bash
Date: Fri, 13 May 2022 12:39:10 +0700 (ICT)

Not a bug.

Do not use && || as if they were a replacement for if then else fi
they aren't. In some simple cases it all works out OK, but not in
general, as you discovered.   If you mean if x; then y; else z; fi
then write that,  not x && y || z

The way and-or lists work, is that the first command (whatever is
to the left of the first && or || at the the current nesting
level ... that is any that occur nested inside some other construct
are not yet seen, but will eventually be used following these
same rules, if that other construct is evaluated) is executed.

To this point it is just like an if statement, in that the list
between the "if" and the corresponding "then" is evaluated.

Then, forever (until the entire and-or list is consumed, there
can be many && and || operators, in any order) when the
operator is reached, if the current exit status is 0, then
if the operator is && we execute the next command in the and-or
list, the exit status changes to the result of that command.
If the operator was || then simply skip to the next && or ||
operator in this and-or list, the exit status does not change,
and continue.

If, when one of those operators is reached the current exit status
is non-zero, we do just the samd, but in reverse, execute the next
command (updating the exit status as that happens) if the operator
is || and skip it leaving the exit status unchanged, if &&

So, in your x && y || z command, x (the [[ command) is executed,
exit status is 0 (true) the && is reached, so we go on and
execute y (the brace group command in your example).  Executing
a group sets the exit status of the group to the status of
the last command in the group that was executed.  In your example
the ls command, which in your case was not zero.
So, when we get to the || operator, the exit status is not
zero, which means we go on and execute the next command z (echo
in your example).

Note particularly that there is no operator precedence between
&& and || - they are the same (unlike in C for example)

This is completely different from if x ;  then y ; else z ; fi
whers what happens in y (if executed) has no bearing at all
upon whether z is executed - there exactly one of y or z
gets executed, never both.  Not true of and-or lists.

The exit status of the whole construct is also different.
In an and-or list, the exit status of that list is that
of whichever command (x, y, or z) was executed last.  The
exit status of the if form is that of whatever command in
the then or else lists (y or z -- cannot be both) was
executed, or 0 if neither was (that is, if x exited non-zero
and there was no else part).  The actual exit status of
x is never used as the exit status of the if command.

So if you mean "if" write "if" not && - using an and-or
list when an if should have been used does not show you
as being a "cool power programmer, using advanced syntax
that the boring newbies do not understand" rather it shows
that you are an incompetant beginner, trying to master
concepts not yet understood, and making a mess of it.

Use the proper construct for what is needed, always.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]