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

Darin Perusich Darin.Perusich at cognigencorp.com
Mon Feb 8 13:17:46 EST 2010


Joe,

Enclosing the block of code within curly brackets does not launch a
subshell. Checkout http://www.tldp.org/LDP/abs/html/subshells.html for
all the gory details on how bash deals w/ subshells.

{ cat $MESSAGEFILE | grep -e "remaining active paths:" -e "timeout of 10
sec" | while read MSGMONTH MSGDAY rest_of_line
do
...
...
done
}
printf "$TMPMNTH $TMPDAY    \t$NUMDISC\t\t$NUMPATH \n"


On 02/08/2010 11:34 AM, Joe Hoot wrote:
> 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
> =====================
> 
> 
> _______________________________________________
> Users mailing list
> Users at wnylug.org
> http://wnylug.org/mailman/listinfo/users_wnylug.org

-- 
Darin Perusich
Unix Systems Administrator
Cognigen Corporation
395 Youngs Rd.
Williamsville, NY 14221
Phone: 716-633-3463
Email: darinper at cognigencorp.com



More information about the Users mailing list