What POSIX says about this (which you probably know already) is: A loop shall enclose a break or continue command if the loop lexically encloses the command. A loop lexically encloses a break or continue command if the command is:
[and just paraphrasing the conditions] - same exxecution environment (ie: not in a subshell) - inside a compound list associated with a loop (including the test list for while/until) - not in the body of a function ... (more or less the obvious useful definition of lexically enclosing). That is the case in which break & continue are required to work. It goes on to say: If n is greater than the number of lexically enclosing loops and there is a non-lexically enclosing loop in progress in the same execution environment as the break or continue command, it is unspecified whether that loop encloses the command. In your example, the number of lexically enclosing loops is 0, 'n' is 1, so the shell is allowed to break from the loop, but not required to. Or in other words, you should not write code like that, because it is not guaranteed to work. oguzismailuy...@gmail.com said: | `break' is not a keyword in the shell, but a special command. That's true. However, 99% of script writers don't see it that way, they believe it is just like "if" or "while" or "done" or "return". That's why the "This is counterintuitive." I would guess - in most cases, the issue isn't quite like yours, but more like f() { for x in a b c; do for y in 1 2 3; do case "$x$y" in (b3) break;; (a2) continue 2;; (c1) break 3;; esac done done } and then called something like for i in 1 2 3 4 5 6 do echo $i; f done and people wonder why that loop never iterates the 2nd time (prints just 1). All this because the script author probably thought that they were writing C, and the b3 break is for the case statement, a2 continue is the y loop, and c1 break the x loop... They can be taught that that's wrong, break/continue do nothing for case statements, and don't count them - but they simply refuse to believe that whatever happens inside the function should affect the caller's flow - an error from the "break 3" is something they can understand, as is just ignoring the "overflow", but not more than that. For people who don't believe that all programming languages should work the same way (usually the same way as the one they learned first) this isn't necessarily as important - but that's a tiny majority of people. kre ps: the NetBSD shell continues to work the way that you want, and does so by deliberate choice - our test suite has a whole stack of tests to make sure this continues to all work "correctly" (doesn't accidentally get changed).