[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, 12 Aug 2010 08:16:21 -0400 |
User-agent: |
Mutt/1.4.2.3i |
On Thu, Aug 12, 2010 at 01:23:20PM +1000, Martin Schwenke wrote:
> Description:
> I don't believe that the following behaviour is sensible or
> matches the standard/documentation:
>
> $ f () { { echo 1 ; echo 2 ; } | while read line ; do echo $line ;
> return 0 ; done ; echo foo ; return 1 ; }
> $ f
> 1
> foo
> $ echo $?
> 1
>
> I expect f to return 0 from within the loop because a function
> is executing.
>
> I know the return 0 is in a subprocess at the end of a
> pipeline... but that whole pipeline is running within a
> function.
You already know the reason it behaves the way it does, so I'm not
quite sure what answer you expect to receive. It's not a bug -- it's
the normal behavior of every shell.
imadev:~$ sh -c 'f() { (return 0); return 1; }; f; echo $?'
1
imadev:~$ ksh -c 'f() { (return 0); return 1; }; f; echo $?'
1
imadev:~$ bash -c 'f() { (return 0); return 1; }; f; echo $?'
1
A return that's run in a subshell doesn't cause the parent shell to
return.
> In
> general I expect to be able to pipe the output of a command
> into a loop and have the loop read lines until some condition
> occurs, at which point my function returns.
Ah, a real question! :)
Use a process substitution in bash:
f() {
while IFS= read -r somevar; do
[[ $somevar = *quit* ]] && return 0
printf '%s\n' "$somevar"
done < <(grep foo bar)
return 1
}
> This could
> obviously be done using a out=$(cmd) subprocess... except in
> the case where cmd can block before producing all of its
> output. Hence, the above seems convenient.
The process substitution doesn't require cmd to finish before it
starts producing data. It's equivalent to a pipeline, except that
the reader doesn't need to be in a subshell.