BREAK(1P)

πŸ’– BREAK(1P) πŸ’–

okay bestie, sit DOWN, because this is a POSIX Programmer's Manual page and we are about to make a tiny little word do a LOT of heavy lifting. this is break, and it is genuinely one of the most iconic escape hatches in all of shell scripting. no cap.


✨ PROLOG ✨

so like, this manual page is part of the POSIX Programmer's Manual. quick lil disclaimer though, because it matters: the Linux implementation of this interface may differ (bestie, consult the corresponding Linux manual page for the deets on Linux behavior), or honestly the interface may not even be implemented on Linux at all. πŸ™ˆ just so you know.


✨ NAME ✨

break β€” exit from for, while, or until loop. literally that's it, that's the whole job, and it eats every single time. πŸ’…


✨ SYNOPSIS ✨

break [n]

✨ DESCRIPTION ✨

okay so here's the tea. if n is specified, the break utility shall exit from the *n*th enclosing for, while, or until loop. if n is not specified, break shall behave as if n was specified as 1. πŸŽ€ execution shall continue with the command immediately following the exited loop. the value of n is a positive decimal integer. if n is greater than the number of enclosing loops, the outermost enclosing loop shall be exited. and if there is no enclosing loop, the behavior is unspecified. 😭 that's the spooky one, remember it.

now, the definition of "enclosing" is where it gets ✨academic✨, so buckle up:

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:

  • Executing in the same execution environment (see Section 2.12, Shell Execution Environment) as the compound-list of the loop's do-group (see Section 2.10.2, Shell Grammar Rules), and
  • Contained in a compound-list associated with the loop (either in the compound-list of the loop's do-group or, if the loop is a while or until loop, in the compound-list following the while or until reserved word), and
  • Not in the body of a function whose function definition command (see Section 2.9.5, Function Definition Command) is contained in a compound-list associated with the loop.

and then, the plot twist 🫢: 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. so like, don't do that. periodt.


✨ OPTIONS ✨

  • None. β€” zero flags, zero fuss, she's low maintenance.

✨ OPERANDS ✨

See the DESCRIPTION. (yeah, they just did that. it's giving "go read the paragraph above", and honestly, valid. πŸ’€)


✨ STDIN ✨

Not used. she does not read your input, she is not listening, she has her own thing going on. πŸ™ˆ


✨ INPUT FILES ✨

None.


✨ ENVIRONMENT VARIABLES ✨

None.


✨ ASYNCHRONOUS EVENTS ✨

Default.


✨ STDOUT ✨

Not used. she's not here to chat, she's here to leave. πŸ’…


✨ STDERR ✨

The standard error shall be used only for diagnostic messages. that's her only yapping channel, and it's for emergencies.


✨ OUTPUT FILES ✨

None.


✨ EXTENDED DESCRIPTION ✨

None.


✨ EXIT STATUS ✨

  • 0 β€” Successful completion. πŸŽ‰ ate, no crumbs.
  • >0 β€” The n value was not an unsigned decimal integer greater than or equal to 1. 🚩

✨ CONSEQUENCES OF ERRORS ✨

Default.

The following sections are informative. (aka, the vibes-only bonus content πŸ¦‹)


✨ APPLICATION USAGE ✨

None.


✨ EXAMPLES ✨

here's the classic, the blueprint, the moment:

for i in *
do
    if test -d "$i"
    then break
    fi
done

and now, the chaos example. πŸ“ the results of running the following example are unspecified: there are two loops in progress when the break command is executed, and they are in the same execution environment, but neither loop is lexically enclosing the break command. (There are no loops lexically enclosing the continue commands, either.)

foo() {
    for j in 1 2; do
        echo 'break 2' >/tmp/do_break
        echo "  sourcing /tmp/do_break ($j)..."
        # the behavior of the break from running the following command
        # results in unspecified behavior:
        . /tmp/do_break

        do_continue() { continue 2; }
        echo "  running do_continue ($j)..."
        # the behavior of the continue in the following function call
        # results in unspecified behavior (if execution reaches this
        # point):
        do_continue

        trap 'continue 2' USR1
        echo "  sending SIGUSR1 to self ($j)..."
        # the behavior of the continue in the trap invoked from the
        # following signal results in unspecified behavior (if
        # execution reaches this point):
        kill -s USR1 $$
        sleep 1
    done
}
for i in 1 2; do
    echo "running foo ($i)..."
    foo
done
bestie. do NOT ship that second one to prod. it is unspecified behavior three separate times in one function. it's giving "haunted code". 😭

✨ RATIONALE ✨

okay so the lore ✨: in early proposals, consideration was given to expanding the syntax of break and continue to refer to a label associated with the appropriate loop, as a preferable alternative to the n method. however, this volume of POSIX.1‐2017 does reserve the name space of command names ending with a <colon>. It is anticipated that a future implementation could take advantage of this and provide something like:

outofloop: for i in a b c d e
do
    for j in 0 1 2 3 4 5 6 7 8 9
    do
        if test -r "${i}${j}"
        then break outofloop
        fi
    done
done

and that this might be standardized after implementation experience is achieved. πŸ‘‘ a queen planning ahead.


✨ FUTURE DIRECTIONS ✨

None.


✨ SEE ALSO ✨

  • Section 2.14, Special Built-In Utilities

Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1-2017, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 7, 2018 Edition, Copyright (C) 2018 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html .

Any typographical or formatting errors that appear in this page are most likely to have been introduced during the conversion of the source files to man page format. To report such errors, see https://www.kernel.org/doc/man-pages/reporting_bugs.html .


πŸ’– and that's the whole page, bestie πŸ’– courtesy of IEEE/The Open Group, dated 2017, filed under BREAK(1P). now go exit some loops responsibly. 🫢✨🌸
πŸ“¦ where this page comes from