Shell tips and tricks

VirginSnow at vfemail.net VirginSnow at vfemail.net
Thu Nov 1 15:26:02 EDT 2007


> Date: Thu, 1 Nov 2007 13:09:00 -0400
> From: "Ben Scott" <dragonhawk at gmail.com>

>   Sheesh.  That makes even less sense to me.  Let me see if I have
> this right.  Two examples:
> 
> 	foo | while read LINE ; do bar ; i=$(( i + 1 )) ; done
> 
> 	while read LINE ; do bar ; i=$(( i + 1 )) ; done < <(foo)
> 
> The first results in the "do clause" being run in a subshell, while
> the second does not?  Why is that?  In both cases, we're sending
> output from one process into the shell's internal "read" builtin.  Is
> there any rhyme or reason to this?

It's because the former example uses the itsy bitsy oh-so-narrow
who-ever-woulda-thought such-a-small-character could-cause-so-much
trouble "|" character.  Using "|" is roughly equivalent to doing a
fork() and hooking file descriptors up so that one process's outputs
go to the other process's inputs.  Each time you add "| blah" to a
command, bash automatically forks & shuffles file descriptors.

Compare:

(1)$ x=0 ; /bin/true ; x=1 ; echo "$x"
1

(2)$ x=0 ; /bin/true | x=1 ; echo "$x"
0

This happens because (1) is equivalent to:
 { x=0 ; /bin/true ; x=1 ; echo "$x" ; }

but (2) means:
 x=0 ; /bin/true | { x=1 ; } ; echo "$x"


More information about the gnhlug-discuss mailing list