By XCU 2.9.2 Exit Status, the ! is right associative and all shells should 
return 1 for "! break" in any context that permits a pipeline; even if the pipe 
only has one element and no "|" involved. I don't see that there's any 
ambiguity; while special, break is still considered a command, not a keyword 
like while or do.

For the last example there is ambiguity, imo, in that a shell might consider 
use of break in the test conditional the same as the loop not being started at 
all, and therefore the setting to 0 if list-2 not executed wouldn't apply. I 
don't believe this is the intent, but I don't see that interpretation excluded 
sufficiently either.

On Tuesday, August 14, 2018 Robert Elz <k...@munnari.oz.au> wrote:

What should be printed from

while :
do
! break
done
echo $?

The standard does not seem to be clear (unless there is
already a bug report that has altered things).

Here it is again on one line, so you can cut&paste
it easily into anything you want to test:

while :; do ! break; done; echo $?

It is clear that the exit status of break here will be 0.
It is also clear that if the "!" applies, then the pipeline
status of the "! break" will be 1.

The exit status of the while loop is supposed to be
that of last command (in the loop body) executed.

But here is that "break" or "! break" - that is, is the
break supposed to immediately jump out of the loop,
bypassing the effect of the ! or does the ! still apply ?

I did a quick test, and shells differ - most print 1 indicating
that the whole pipeline (! break) is evaluated, the loop then
ends, and the status of the pipeline (1) is the result.

But there are shells (mksh, pdksh, and the FreeBSD sh are
three I found) which print 0, indicating that on "break" the loop
immediately exits, the exit status is that from break (0),
not from ! break.

Which is correct?

I know this is of little practical relevance -- no-one sane is
going to write "! break" (it looks as if it is intended to mean
"don't break" but that is definitely not correct) but this kind
of little quirk, and working out how the standard spedifies it
appeals to me ...

Note that everyone agrees that in

while :
do
break && echo broken
done

"broken" is not printed (even though "break" is true).

The seemingly stranger case ...

while ! break
do
false
done

is actually simpler, here it doesn't matter if the ! is evaluated
or not, the break causes the loop to terminate (not execute
he body at all), which means that the exit status must be 0.

Only yash of the shells I tested gets that one wrong, which is
a little odd, as it handles
while false; do :; done; echo $?
correctly.

kre



Reply via email to