Skip to main content
4 of 5
replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/

The right explanation has already been given by jsbillings and geekosaur, but let me expand on that a bit.

In most shells, including bash, each side of a pipeline runs in a subshell, so any change in the shell's internal state (such as setting variables) remains confined to that segment of a pipeline. The only information you can get from a subshell is what it outputs (to standard output and other file descriptors) and its exit code (which is a number between 0 and 255). For example, the following snippet prints 0:

a=0; a=1 | a=2; echo $a 

In ksh (the variants derived from the AT&T code, not pdksh/mksh variants) and zsh, the last item in a pipeline is executed in the parent shell. (POSIX allows both behaviors.) So the snippet above prints 2.

A useful idiom is to include the continuation of the while loop (or whatever you have on the right-hand side of the pipeline, but a while loop is actually common here) in the pipeline:

cat junk | { while read var ; do x=55 ; done echo x=$x } 
Gilles 'SO- stop being evil'
  • 866.5k
  • 205
  • 1.8k
  • 2.3k