Shell tips and tricks
Steven W. Orr
steveo at syslang.net
Thu Nov 1 16:47:21 EDT 2007
On Thursday, Nov 1st 2007 at 15:26 -0000, quoth VirginSnow at vfemail.net:
=>> 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?
This is interesting because what you're really generating here is a
detached process which is running foo and which is writing to a pty. That
pty is being read by your shell script. The end result is that the while
loop in this case is *not* in the scope of a child process created by a
pipe. Don't forget: pipe in shell is not pipe(2). Pipe in shell is a whole
sequence of fork/dup/pipe/close/exec calls.
=>
=>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.
=>
On Thursday, Nov 1st 2007 at 15:42 -0000, quoth Ben Scott:
=>On 11/1/07, VirginSnow at vfemail.net <VirginSnow at vfemail.net> wrote:
=>> 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.
=>
=> Right, but doesn't the Process Substitution do a similar thing? My
=>question is not "Why does a subshell ever get used at all?", but "Why
=>is a subshell used sometimes but not others?". Again, compare these
=>two:
=>
=> foo | while read LINE ; do bar ; i=$(( i + 1 )) ; done
=>
=> while read LINE ; do bar ; i=$(( i + 1 )) ; done < <(foo)
=>
=> For the second example, the shell has to fork() and exec() the "foo"
=>program, and hook up it's stdout file descriptor to the stdin file
=>descriptor that gets passed to the "do clause". Why doesn't that need
=>a subshell?
The | character is *exactly* the same as the whole meshugena sequence you
have to do in C of fork/close/dup/pipe/exec nonsense. It would make zero
sense for access to variables which happen to have the same name on
opposite side of the pipe to be the same instance. :-)
--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
More information about the gnhlug-discuss
mailing list