help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] break and continue inside subshells


From: Bob Proulx
Subject: Re: [Help-bash] break and continue inside subshells
Date: Fri, 19 Oct 2012 00:04:20 -0600
User-agent: Mutt/1.5.21 (2010-09-15)

Glenn Morris wrote:
> ## This is fine:
> ( echo 1; break; echo 2 )
> 
>   -> Prints "1", bash: break: only meaningful in a `for', `while', or
>   `until' loop, "2"
> 
> So a "break" inside a subshell has no effect (as expected).

There isn't a loop context for it.  It is a shell process that is
forked into a child.  The break happens in the child process.

> ## This is suprising:
> for f in 1 2; do
>   (
>     echo $f
>     break
>     echo X
>   )
>   echo Y
> done
> 
> It prints "1", "Y", "2", "Y".
> So now the break does have an effect, but not the expected one. It just
> jumps to the end of the subshell, not the next loop iteration. ksh and
> zsh seem to behave in the same way, but it seems odd to me...

What Dan said but I wanted to emphasize that the parens fork a child
process.  Therefore the break happens in the child.  It is a process
fork and the child is a clone of the parent and is operating within
the loop context since the parent was operating within a loop when the
process was forked off.  But it is still a child process that is going
to exit in the next moment.  Everything about the child will evaporate.

Thinking about it like that, that this is happening in a child
process, how would the child process communicate back to the parent
that it should 'break [n]' or 'continue [n]' the enclosing loop, or
possibly the Nth enclosing loop?  All it can do is exit.  It is
supposed to be a light weight process fork.  If it were heavier it
might be a full external shell script or binary program there.
Complex flow control like 'break [n]' and 'continue [n]' especially
with a possible N specified is not going to have a way to communicate
that flow control back to the parent process.

In fact that isolation of forking a subshell is one of the main
reasons to use a subshell instead of a group command list using curly
braces.  Anything that happens in a forked child is in a different
process and will evaporate when that child process exits.  If you want
things to affect the current shell then it needs to avoid the subshell
(cmd) parens and operate within the current shell using { cmd; } curly
braces.

If you try the loop using curly braces it will work as you expect
because then there won't be a child process and everything will
operate within the original process.

Hope that helps,
Bob



reply via email to

[Prev in Thread] Current Thread [Next in Thread]