Craig Russell

Web n That

I ♡… the web… php… html… css… linux… shell scripting… folding paper… dog walking… sandwiches… being outside… and most of all @vicuol ☺

BASH Variable Scope in While Loop

December 8th, 2008

Here’s an annoying little foible of BASH shell scripting.

I’ve been trying to writea script to test authorization against a list of servers, and fire off an email if any of the servers doesn’t respond. The lis tof servers is in a text file, and I’ve got a while loop to itterate through, testing line by line. If any of the tests fails then, I’d change a flag variable from its default value of “FALSE” to “TRUE”. After the loop I can test the value of the flag variable, and send an email accordingly.

The problem I was having is that the variable scope didn’t seem to extend beyond the while loop, so the final check always showed that the flag was set to FALSE, even if it was changed within the loop.

My original script looked something like this…

[bash]
SENDMAIL= grep "^server:" servers.file | while read line; do
if [ testauth() ]; then
SENDMAIL="TRUE"
fi
done

if [ SENDMAIL ]; then
sendMail()
fi
[/bash]

The problem is that, I’ve piped my file through grep and in to the while loop. Because of the way the shell handles piped commands, the variable scope is limited to within the while loop. To get around this problem, you have to remove the pipe in to the while loop. In this case I chose to output to a temp file then read it in, but you can also pipe to a variable, then loop over the variable.

[bash]
SENDMAIL= grep "^server:" servers.file > servers.tmp

while read line; do
if [ testauth() ]; then
SENDMAIL="TRUE"
fi
done < servers.tmp

if [ SENDMAIL ]; then
sendMail()
fi
[/bash]

  • craig552uk
  • Fernando

    Sweet, thanks man, you just saved me a ton of trouble and helped me with this problem I’ve been banging my head with for the past hour!

  • Patrick

    Thanks! I was having similar issues and you helped me solve them via your example.

  • pre

    Thanks!

  • http://www.stereo.org.ua/ Alex

    Yep!
    I suspected the pipe was the culprit…

  • taylor

    I spent forever on this.  Your post fixes my problem, thank you!