3 ms·
I use this exact pattern a lot. One thing to consider is that in the process substitution version, do_something can't modify the enclosing variables. The vast m
by chriswarbo 5y ago
I use this exact pattern a lot. One thing to consider is that in the process substitution version, do_something can't modify the enclosing variables. The vast majority of the time I want to modify variables in the loop body and not the generating process, but it's worth keeping in mind.
One common pattern I use this for is running a bunch of checks/tests, e.g.
EXIT_CODE=0
while read -r F
do
do_check "$F" || EXIT_CODE=1
done < <(find ./tests -type f)
exit "$EXIT_CODE"
This is a more complicated alternative to the following:
find ./tests -type f | while read -r F
do
do_check "$F" || exit 1
done
The simpler version will abort on the first error, whilst the first version will always run all of the checks (exiting with an error afterwards, if any of them failed)
- fiddlerwoaroof 5y agoI usually write zsh scripts and I think there’s a shell option in zsh that allows the loop at the end of the pipe to modify variables in the enclosing body: I remember at least one occasion where I was surprised about this discrepancy between shells.
- aaaaaaaaaaab 5y agoInteresting! Indeed, Greg's BashFAQ notes it too: https://mywiki.wooledge.org/BashFAQ/024 https://mywiki.wooledge.org/BashFAQ/024 >Different shells exhibit different behaviors in this situation: >- BourneShell creates a subshell when the input or output of anything (loops, case etc..) but a simple command is redirected, either by using a pipeline or by a redirection operator ('<', '>'). >- BASH, Yash and PDKsh-derived shells create a new process only if the loop is part of a pipeline. >- KornShell and Zsh creates it only if the loop is part of a pipeline, but not if the loop is the last part of it. The read example above actually works in ksh88, ksh93, zsh! (but not MKsh or other PDKsh-derived shells) >- POSIX specifies the bash behaviour, but as an extension allows any or all of the parts of the pipeline to run without a subshell (thus permitting the KornShell behaviour, as well).
- vbezhenar 5y agoCheck out bash lastpipe option.