On 5/24/25 10:43 AM, Steve Newcomb wrote:
Bash Version: 5.2 Patch Level: 15 Release Status: releaseDescription: In the following script, #!/bin/bash true && { echo here 1 test "$PIPESTATUS" "!=" "0" #echo here 2 } || { echo here 3 } The output is: here 1 here 3 ("here 3" should never be output, I think, because of the grouping)
OK. Let's take a look at AND-OR lists. The `&&' and `||' operators are
left-associative and have equal precedence. That means that something
like
A && B || C
is parsed and executed as if it were
{ A && B; } || C
where C's execution is determined by the exit status of the preceding
AND-OR list (or group command, if you like), which is either A's non-zero
status or the status B returns. So if A fails, or B fails, C is going to
be executed. So far, so good.
When the command above is executed, the test command fails, since
PIPESTATUS[0] == 0 (the `echo here 1' succeeded). That means the group
command that's on the right side of `&&' (`B') fails, which means the
`&&' part of the AND-OR list fails, which means that the `echo here 3'
(`C') is executed.
This is how POSIX shells behave. You can make it a portable test by
replacing the "$PIPESTATUS" with "$?".
If "#echo here 2" is uncommented the output is here 1 here 2 (which is what I would expect)
There is nothing to prevent the execution of `echo here 2'; it succeeds; the right side of the `&&' list succeeds; the `&&' AND-OR list succeeds; the `echo here 3' is not executed.
Another way to get the correct behavior is to change "$PIPESTATUS" to, e.g. "$PATH".
Well, sure. It's highly likely that "$PATH" will not be "0", so the test
command will succeed, and so on.
Note, as others have, that this AND-OR shorthand is not equivalent to
if A; then B; else C
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU [email protected] http://tiswww.cwru.edu/~chet/
OpenPGP_signature.asc
Description: OpenPGP digital signature
