Hi, I have two shell scripts that do the same thing, but are written differently. The first one works:

size=0
pattern=foo

for file in *
do
	[ ! -f $file ] && continue
	
	if grep $pattern $file > /dev/null
	then
		tsize=`cat $file |wc -c`
		size=`expr $size + $tsize`
		echo "size is: $size"
	fi
done
echo "Total size of files containing $pattern is: $size"

With the output of

$ ./foofinder
size is: 34
size is: 77
size is: 223
size is: 478
size is: 758
size is: 855
Total size of files containing foo is: 855

But, I then have this script:

pattern=foo
total=0

ls -l | while read j1 j2 j3 j4 fsize j5 j6 j7 fname 
do
	[ ! -f $fname ] && continue

	if grep $pattern "$fname" > /dev/null 2>%1
	then
		total=`expr $total + $fsize`
		echo "size is: $total"
	fi
done
echo "Total size of files containing $pattern is: $total"

With the output of

$ ./foofinder2
size is: 34
size is: 77
size is: 223
size is: 478
size is: 758
size is: 855
Total size of files containing foo is: 0

Basically, I want to know why the second script returns the line:

Total size of files containing foo is: 0

, when the last known value of the $size variable is 855, but the first script gets it right? Why should they be any different?

Your help with this would be greatly appreciated, as I am just new to learning shell scripting, and I would like to know why they are producing different results.

Thanks!

>Basically, I want to know why the second script returns the line:
> Total size of files containing foo is: 0 Variable scope problem in the while loop with | (pipe)
More here.

Hey there,

Just in case you have to do it the second way, this form works in bash 3.x (possibly earlier versions) and avoids the variable scoping problem while maintaining the integrity of the command you were feeding to the pipe.

while read j1 j2 j3 j4 fsize j5 j6 j7 fname 
do
	[ ! -f $fname ] && continue

	if grep $pattern "$fname" > /dev/null 2>%1
	then
		total=`expr $total + $fsize`
		echo "size is: $total"
	fi
done <<< "`ls -l`"
echo "Total size of files containing $pattern is: $total"

hope it helps :)

, Mike

Thanks for that!

I used the 3rd option that is sh-compliant, with the fix of putting the last echo inside the } bracket.

I didn't realise there was an issue with ammending the variable value that was set outside the loop - it's not anywhere in my training! So, at least i've learned from my mistake!

Thanks very much for your help - greatly appreciated.

This article has been dead for over six months. Start a new discussion instead.