bug-bash
[Top][All Lists]
Advanced

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

Re: return from function doesn't work when used in tail of pipeline


From: Greg Wooledge
Subject: Re: return from function doesn't work when used in tail of pipeline
Date: Thu, 19 Aug 2010 08:37:33 -0400
User-agent: Mutt/1.4.2.3i

On Thu, Aug 19, 2010 at 11:12:03AM +0100, Marc Herbert wrote:
> > On Thu, 12 Aug 2010 08:16:21 -0400, Greg Wooledge <wooledg@eeg.ccf.org>
> >> A return that's run in a subshell doesn't cause the parent shell to
> >> return.
>
> Are there many people actually using
> "return" to exit a subshell? That would not really make code easy to
> read.

You misunderstood, or I was unclear.  I meant, "A return statement that
is issued inside a subshell, inside a function, does not cause the parent
shell's function call to return."

Thus:

  imadev:~$ f() { (return); echo still here; }; f
  still here

If I remember the context of this thread, the original question was
something like this:

  f() {
    grep foo bar | while read stuff; do
      ... || return
    done
    echo still here
  }

And the OP didn't understand why the return command inside the subshelled
loop body failed to cause the function "f" to terminate.

I was simply trying to point out that the return command *is* inside a
subshell and therefore doesn't cause the function of which it's a
"grandchild" to return to its caller, any more than setting a variable
inside the subshell would cause it to be set in the remainder of "f"
after the subshell terminates.

My preference, if the code is going to retain that structure (pipe into
a while loop), would be to use neither exit nor return inside the loop;
I would use break.  I agree that using return or exit inside the loop
would be unclear to the reader (since either one would effectively only
be doing what break does).

If application logic requires terminating "f" from inside the loop,
then the code must be rewritten, or the script must be switched from
bash to Korn shell (real, not pdksh).

In bash:

  f() {
    while read stuff; do
      ... || return   # kills "f"
    done < <(grep foo bar)
    echo still here
  }

In ksh88 or ksh93:

  f() {
    grep foo bar | while read stuff; do
      ... || return    # kills "f" because the while is not in a subshell
                       # because ksh is different from all the others here
    done
    echo still here
  }

> the ability from a subprocess to exit his parent would be quite a
> dramatic exception to the rule where a child can never have any
> side-effect on his parent.

Well said.



reply via email to

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