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.