Variables scope.

Hi ,
I'm trying to change the variable value in a while loop , however its not working it seems that the problem with subshells while reading the file.

#!/bin/sh
FLAG=0;
cat filename | while read data
do
FLAG=1;
done

echo $FLAG

Should display 1 instead displays 0

It will only display the value of FLAG as 1 when the condition is satisfied,that means there is some file you are trying to cat and reading lines. So check for the file first.

Thanks..

The file exists , but since there is a while loop each reads a file , it creates a subshell , so the value is lost as soon as while loop ends.

#!/bin/sh
FLAG=0;
while read data
do
FLAG=1;
done < filenname

echo $FLAG

try this u will get flag value 1

Unfortunately that only works in bash shell.

Hi,

First yo chech for the file existence and then

FLAG=0;
while read file
do
FLAG =1;
done < input_file
echo "$FLAG"

I think this should work...

There no single explanation and the main problem is not whether the file exists. It is what shell is being used. Consider this:

$ cat fcheck
#!/bin/sh

FLAG=0;
cat filename | while read data
do
echo "data=$data"
FLAG=1;
done

echo $FLAG

Bash

$ bash fcheck
data=line1
data=line2
0

Bourne:

$ sh fcheck
data=line1
data=line2
0

Korn:

$ ksh fcheck
data=line1
data=line2
1

So for sh, the behavior is as expected.

So is there a way it can be done in sh shell.

The idea is not to spawn a sub-shell:

$ cat fcheck
#!/bin/sh

FLAG=0;
while read data
do
        echo "data=$data"
        FLAG=1;
done < filename

echo $FLAG
$ ./fcheck
data=line1
data=line2
1

This was already suggested by abhisek.says and contrary to what you reported, it evidently DOES work in Bourne shell.

HTH

I just tested it under a Solaris machine and it does NOT work.

Script:

#!/bin/sh

FLAG=0;
while read data
do
        echo "data=$data"
        FLAG=1;
done < filename

echo $FLAG

Output:

./fcheck
data=line1
data=line2

You are right - I must have some mistake. It does NOT work in Bourne shell. Infact I could only make it work in ksh.

another way to do that in bash is :

#!/bin/sh
FLAG=0
exec 4<&0
exec <$1
while read line
do
    FLAG=1
done
echo $FLAG
exec 0<&4 4<&-

$1=the file u want to read

Setting FLAG within a while loop works in bash, ksh, ash, zsh. It does not work in sh (Bourne shell) because redirection causes a subshell. From the sh(1) manpage on Solaris.

Today i needed a new script which reads line for line and i tried a for loop.
So I made the following script:

bla=2
echo $bla
for i in `cat ./config.txt`
do
  echo $i
  bla=5
done

echo $bla

First $bla =2 and by the second print $bla=5.
Tested under bourne shell on Solaris and Suse.