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