Changing variables in a BASH while loop April 2, 2009

Posted by idimmu in linux.
There is an error that I often run in to when working with files and while loops in BASH. Often I have scripts similar to the following, where I cat a file and read it in using a while loop to process variables in the file:


#!/bin/bash

count=0;

cat testfile | while read line
do
count=$(($count+1));
echo $count;
done

echo "Total $count";


and using the following test data in testfile as:


cake
pie
thongs


I would expect an output like:


1
2
3
Total 3


But instead I get:


idimmu@boosh:~$ ./t.sh
1
2
3
Total 0


What is happening is due to the | (pipe) bash is forking and creating a new process so any variables we are altering and changing ($count) are being manipulated in the child process, and then lost when the subprocess finishes!

A lot of people I've spoken to who have seen this either completely change their code structure to accommodate, or worse, change shell completely to something like KSH!

If we tweak our script ever so slightly, and read the file in at the end of the BASH while loop...


#!/bin/bash

count=0;

while read line
do
count=$(($count+1));
echo $count;
done < testfile

echo "Total $count";


everything changes :)


idimmu@boosh:~$ ./t.sh
1
2
3
Total 3


and we get the output we expect! An excellent book on how to actually use BASH can be found here: Learning the bash Shell: Unix Shell Programming (In a Nutshell (O'Reilly))!

Tags

Friends

twitter

  • @smortions nhs? thats unusually cheap !
  • @mikepea ooh urgh ive got somewhere to be at 7 else id be love to! is it a regular tuesday thing?
  • is rocking veritas cluster server right now!
  • @fluffyemily yay!
  • @robinhood you are a twat

lastfm

  • 3 Inches of Blood – Execution Tank
  • 3 Inches of Blood – 12:34
  • 3 Inches of Blood – All of Them Witches
  • 3 Inches of Blood – At the Foot of the Great Glacier
  • 3 Inches of Blood – Snake Fighter
  • 3 Inches of Blood – Call of the Hammer
  • 3 Inches of Blood – Preacher's Daughter
  • 3 Inches of Blood – Fierce Defender
  • 3 Inches of Blood – Silent Killer
  • 3 Inches of Blood – Rock In Hell

IdleRPG Stats

  • 1 SpacedMonkey 50
  • 5 Appocomaster 49
  • 10 HRH_H_Crab 48

Lottery

  •             () 
  •             () 
  •             () 
  •             () 
  •             () 
  •             ()