Red Hat Bugzilla – Bug 63850
How does one set variables in a piped to 'while' statement
Last modified: 2007-04-18 12:42:11 EDT
From Bugzilla Helper:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows 95)
Description of problem:
After reading bug 42282, I realize this isn't considered a bug but I'm puzzled
as to the usefullness of bash. In my case, I'm extracting information from a
file and sending this to a "while" construct. Any variables set in the while
are lost on the way out. This is unexpected and undocumented behaviour,
inconsistent with shells such as Korn (which is what I'm porting scripts from).
echo "xx" | while [ 1 ]; do
xxx=123; break; done
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. write any script which pipes information to "while"
2. set an environment variable within the "while"
3. try to use the varilable outside of the "while"
Actual Results: The variable takes on the value (or is unset) as it was before
entry to the while. In my case, I'm using a read statement within the while but
I don't think that's significant based on bug# 42282.
Expected Results: In literally any other enviroment I've seen, any variable
set within a while loop remains set outside of the while loop. The addition of
the pipe (ex: echo "a" | while ...) apparently causes the while loop to be run
as a sub-process and everything done to the environment is lost. These results
are completely different if a pipe is not used.
The major issues are that the difference results are inconsistent, not
expected, not intuitive, and NOT documented anywhere; nor is there any
suggested work-around for this. Took me hours to figure this out. Based on the
amount of bug-reports I've seen, this seems to be at least worthy of a
documentation note under 'read/while/until/for' stating that "if used at the
end of a pipe sequence, any variables set will be lost due as intended by the
I'm classifying this as a normal bug; fully expecting this to be closed. I
would have put it as "low" but any workarounds I've found are often more
complex that the original code. Since I'm converting "ksh" scripts, I consider
this to be a "loss of function"; enough to make me consider scrapping bash
(well, I'd leave it for the system to use - it apparently doesn't do anything
Incidentally, one use of a "piped while read" statement is to get around
problems when using "for" with a list produced by "grep" when there are lots of
elements (overflowing the command buffer). When people start implementing big
Linux systems, then scripts such as rc.sysinit will malfunction (see loop
around line 475 and other places) and switching the "overflowed for" to a "pipe
while read loop" (which handles unlimited data) won't update "rc" as expected
so the subsequent "did we have problems" check will always say 'no
problems'. 'twill be interesting to see how this is handled. Of course, this
won't be a problem if Linux is only targetted at small systems.
I may have to convert back to "ksh".
This is actually the intended and POSIX compliant behavior (pipes run in a
different process space -> don't share environment).