I need help with "while" Vs "for" bizarre behavior

I need help with "while" Vs "for" bizarre behavior

Post by Farid Hamjav » Sun, 05 Dec 1999 04:00:00



I have no explanation of my own for
explaining why this bizarre behavior
is happening.  Running under bash,
I am experiencing that using "while"
in a script leads to some bizarre
behavior. But not when using "for".

The strange behavior is that using "while"
value of ${VarABC} is somehow manipulated!!

Using debug print lines, I do know that
value of ${VarABC} should be a "1" but
it is not.  When using "for" and everything else
is the same, it behaves normally like it should
and that value of ${VarABC} is equal to "1"
So, somehow, something is pulling the
rug, so to speak, underneath ${VarABC}.

I even constructed a test case where the
"while" loop only executed once. Even then,
value of ${VarABC} comes out to be wrong.

Questions:
Is there anything that I am missing that is
causing this bizarre behavior?

What do I need to know (that I guess I don't)
about "while" usage that may shed light on this
mystery?

BTW, I don't seem to have this problem under
Bourne shell. But I want to use bash so I like
to resolve this  mystery.

#initialize VarABC
VarABC=0
#
#
cat ${filename}|while read thisline <-- does not work
for thisline in `cat ${filename}`   <-- works

do
    #do bunch of stuff....
    #this is the only place VarABC get set.
    VarABC=1
    #do bunch of stuff....
    #here value of VarABC is 1
done
#
#here value is 0
echo "VarABC=${VariableABC}"

Thanks,
Farid

 
 
 

I need help with "while" Vs "for" bizarre behavior

Post by Eric Amic » Mon, 06 Dec 1999 04:00:00


[snip]
Quote:> Using debug print lines, I do know that
> value of ${VarABC} should be a "1" but
> it is not.  When using "for" and everything else
> is the same, it behaves normally like it should
> and that value of ${VarABC} is equal to "1"
> So, somehow, something is pulling the
> rug, so to speak, underneath ${VarABC}.

[snip]

Quote:> #initialize VarABC
> VarABC=0
> #
> #
> cat ${filename}|while read thisline <-- does not work
> for thisline in `cat ${filename}`   <-- works

I'm assuming the echo after the loop is simply a typo because the problem
still exists when referring to the right variable.  The problem is that
the loop body is run in a subshell because of the pipe with the while
version; as a result, the while loop manipulates a local copy of VarABC.
The while loop will behave as expected if you use redirection and not
piping, as in

while read thisline
do
# whatever
done <$filename

There's another big difference between the two loops: the while loop makes
one pass per input line, but the for loop makes one pass per input *word*.
The input data layout may be such that it doesn't matter in this case, but
you should definitely keep it in mind for the future.

--
Eric Amick
Columbia, MD


 
 
 

I need help with "while" Vs "for" bizarre behavior

Post by Dale Hagglun » Tue, 07 Dec 1999 04:00:00



> The strange behavior is that using "while" value of ${VarABC} is
> somehow manipulated!!
>       VarABC=0
>       cat ${filename} | while read thisline <-- does not work
>       do
>           VarABC=1
>       done
>       echo "VarABC=${VariableABC}"
> [The] value of ${VarABC} should be a "1" but it is not.  When using
> "for" and everything else is the same, it behaves normally like it
> should and that value of ${VarABC} is equal to "1".
> Is there anything that I am missing that is causing this bizarre
> behavior?

Yep.  This behaviour is a ``feature'' of some versions of the bourne
shell.

Quote:> What do I need to know (that I guess I don't) about "while" usage
> that may shed light on this mystery?

In a construct like

        cat file |
        while read var ; do ... done

the while loop is executed in a subshell.  A subshell cannot affect
the values of variables in its parent shell.  The assignment to VarABC
does indeed take place, but to the version of the variable in the
subshell, not the one in the surrounding parent process.

The for loop works as expected because it does *not* execute in a
subshell.  But, if you wrote the for loop as

        (for ... ; do ... done)

you would see exactly the same behaviour.  The parens force the for
loop into a subshell.

Quote:> BTW, I don't seem to have this problem under Bourne shell. But I
> want to use bash so I like to resolve this mystery.

Well, there are many shells that can be called bourne shells.  The
implementation details of pipelines vary from one to another.  It is
just such a detail that causes the behaviour you see.  In particular,
I believe that ksh explicitly runs the final command of a pipeline in
the current shell to make the loop you wrote execute as it looks like
it should.

If you want to write a script that is portable across several variants
of the bourne shell, this is one of the gotcha's you'll have to be
aware of.

Dale.

 
 
 

I need help with "while" Vs "for" bizarre behavior

Post by Chet Ram » Wed, 08 Dec 1999 04:00:00




>I have no explanation of my own for
>explaining why this bizarre behavior
>is happening.  Running under bash,
>I am experiencing that using "while"
>in a script leads to some bizarre
>behavior. But not when using "for".

This is the same issue that is discussed in the Bash FAQ, question E4.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
( ``Discere est Dolere'' -- chet)