I have the following script running with nohup on one of my servers:
#!/bin/bash
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#set log number
#i=1
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#Check if log exits, if so incrememnt log number up so we don't clobber
#while [[ -f /tmp/ethtool.$i.dump ]];do let i=i+1;done
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#Location of streamer log
LOGFILE=/opt/VideoServer/logs/streamer_log.txt
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#Before tailing logs, dump current eth information
ethtool -S eth3 > /tmp/ethdump.$(date "+%m.%d.%y.%H.%M").start
cat /proc/net/cxgb3/ofld_dev0/stats >> /tmp/ethdump.$(date "+%m.%d.%y.%H.%M").start
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#Start tailing the log
tail -F $LOGFILE|while read line;do
line=($line)
if [[ "${line[2]}" == "E" ]]; then
echo "${line[*]}" | grep -q "FX_HR_Timer_Sink::restart_timer_"
if [[ $? -eq 0 ]];then
LOGTIME=$(date "+%m.%d.%y.%H.%M")
echo "${line[*]}" > /tmp/ethdump.$LOGTIME
echo >> /tmp/ethdump.$LOGTIME
echo >> /tmp/ethdump.$LOGTIME
ethtool -S eth3 >> /tmp/ethdump.$LOGTIME
echo >> /tmp/ethdump.$LOGTIME
echo >> /tmp/ethdump.$LOGTIME
cat /proc/net/cxgb3/ofld_dev0/stats >> /tmp/ethdump.$LOGTIME
#let i=i+1
fi
fi
done
All it's doing is watching a log file, and looking for errors (as indicated by E in the third column) and then checking to see if that error is a specific problem we're having, and if so, dumping some information about the interface. The script runs perfectly, and creates the dump files exactly as expected. The one thing I don't understand is why it seems to create two processes when it is run:
I assume it has something to do with creating subshells when the script is run, but as I (unfortunately) learned most of my scripting and whatnot from trial and error, and not from real book learning, simple things like this escape me.
I've tried to do some reading, and while I understand shells and subshells to a point in theory, I'm having a hard time understanding what's going on in practice. Could anyone give me the idiots explanation of why I'm spawning two processes to do one job? (I know the script isn't running twice at the same time...only one dump file is being created).
So there's no way of knowing what process is doing what? If one pid were killed, would the other keep running but not do anything, or would it just spawn the process again once the loop went through again.
But I couldn't get it to work. I think it has something to do with the colour coding used in the log files. Had I done it like this, would it have not spawned the second shell?
Is there a better way I could have accomplished this goal? I've only recently started trying to parse logs in real time like this, and aside from learning perl (which I hope to do eventually) I can't think of who better to have accomplished this.
I'm sorry, could you expand on this a bit? I'm not sure what you mean by modifying variables inside the loop...where else could I have done it?
This is one of the subtle differences you need to watch out for when porting shell scripts. Consider a slightly modified version of Jim's example, i.e.
#!/bin/bash
a=1
cat $0 | while read rec
do
(( a++ ))
done
echo $a
Bash outputs 1 but ksh93 and zsh output the number of lines in the script file (10)
I should have been more precise in my post. What I said does not refer to all bash while loops, but to bash while loops which read from a pipe, as does the snippet of code which I quoted in my earlier post.
Apologies for any confusion that my lack of precision may have caused.
Regards,
Alister
---------- Post updated at 11:23 PM ---------- Previous update was at 11:10 PM ----------
Absolutely. Also, the differing behaviors are posix-compliant (you did not imply otherwise, just stating it in case anyone else is wondering ;)):