On Thu, 04 Apr 2024 20:39:51 -0400 "Dale R. Worley" <wor...@alum.mit.edu> wrote:
> "Linde, Evan" <eli...@okstate.edu> writes: > > In a loop constructed like `... | while read ...`, changes to > > variables declared outside the loop only have a loop local > > scope, unlike other "while" or "for" loops. > > Yeah, that's a gotcha. But it's a general feature of *pipelines*, > documented in > > Each command in a pipeline is executed as a separate process (i.e., in > a subshell). See COMMAND EXECUTION ENVIRONMENT for a description of a > subshell environment. If the lastpipe option is enabled using the > shopt builtin (see the description of shopt below), the last element of > a pipeline may be run by the shell process. > > To circumvent that, I've sometimes done things like > > exec 3<( ... command to generate stuff ... ) > while read VAR <&3; do ... commands to process stuff ... ; done > exec 3<- > > You may be able to condense that to > > { > while read VAR <&3; do ... commands to process stuff ... ; done > } <( ... command to generate stuff ... ) > Owing to while being a compound command, it need not be solely enclosed by another. Optionally, read's -u option may be used to avoid a dup(2) syscall for each line read. More importantly, the necessary redirection is missing. As such, your example could be amended as: while read -r -u3 var; do ... processing commands ...; done 3< <(... generating commands ...) In the event that the processing commands are known not to attempt to read from STDIN, that may be further reduced to: while read -r var; do ... processing commands ...; done < <(... generating commands ...) -- Kerin Millar