bug-bash
[Top][All Lists]
Advanced

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

Re: Scope change in loops with "read" built-in


From: Kerin Millar
Subject: Re: Scope change in loops with "read" built-in
Date: Fri, 5 Apr 2024 10:10:02 +0100

On Thu, 04 Apr 2024 20:39:51 -0400
"Dale R. Worley" <worley@alum.mit.edu> wrote:

> "Linde, Evan" <elinde@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



reply via email to

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