[WNYLUG-Users] Burnt by Bash AGAIN!!!!

Joe Hoot joehoot at gmail.com
Mon Feb 8 11:34:42 EST 2010


Hi all,

I don't know if others have had this happen to them.  However, I have run into this 3-4 times now and have been beating my head against the wall (poor wall) attempting to debug this.  I hope my memory will hold up next time so that I'll remember that bash doesn't handle pipes in the way I would want them to.  But I figured I'd toss this out to the list in case anyone else runs into these problems once in awhile and doesn't want to put dents in their wall:

Here's an example of why I was banging the wall:

#!/bin/bash
#  - numdiscs.sh - script to check /var/log/messages* to see if iSCSI has disconnects and if there
#                              have been any dm-multipath path failures because of the iSCSI disconnects
#
MESSAGES=$(ls /var/log/messages*)
TMPMNTH=AAA
TMPDAY=0
FIRSTROUND=0

printf "Date\tDisconnects\tPath Failures\n"
printf "=====================================\n"

for MESSAGEFILE in $MESSAGES
do
  cat $MESSAGEFILE | grep -e "remaining active paths:" -e "timeout of 10 sec" | while read MSGMONTH MSGDAY rest_of_line
  do
     if [ "$MSGMONTH $MSGDAY" != "$TMPMNTH $TMPDAY" ]; then
        if [ $FIRSTROUND -ne 0 ]; then
          printf "$TMPMNTH $TMPDAY    \t$NUMDISC\t\t$NUMPATH \n" 
        fi
        FIRSTROUND=1
        TMPMNTH=$MSGMONTH
        TMPDAY=$MSGDAY
        NUMDISC=0
        NUMPATH=0
     fi

     echo $rest_of_line | grep "timeout of 10 sec" 2>&1 1>/dev/null
     if [ $? -eq 0 ]; then
        NUMDISC=`expr $NUMDISC + 1`
     fi
     echo $rest_of_line | grep -e "remaining active paths: 1" -e "remaining active paths: 0" 2>&1 1>/dev/null
     if [ $? -eq 0 ]; then
        NUMPATH=`expr $NUMPATH + 1`
     fi
  done 
  printf "$TMPMNTH $TMPDAY    \t$NUMDISC\t\t$NUMPATH \n" 
done

##### END 

In Bash, the following line spawns a subshell for grep + another subshell for while.  Well, when you spawn a shell, you'll lose your variables for the parent shell.
In Ksh, this is handled the way I want it to by doing it within the parent shell without spawning subshells (I believe).  So this works the way I would want it to and allow me to use my variables further along in the program.

  cat $MESSAGEFILE | grep -e "remaining active paths:" -e "timeout of 10 sec" | while read MSGMONTH MSGDAY rest_of_line

The easy fix for me was to change the first line to be #!/bin/ksh and all works as expected.


Cya,
Joe

=====================
Joseph R. Hoot
Network Penguin
joe at networkpenguin.com
GPG KEY:   7145F633
=====================




More information about the Users mailing list