0

I'm trying to keep a external counter in my bash script.

As most of the script is specific to what it's for, I'm only going to insert the pertinent parts that I can't seem to get working. Everything before does get defined. Also before someone comments about the cat, I tried (< $TMPFILE) as well. The issue appears to be not writing to the file.

#!/bin/bash
TMPFILE="/tmp/nettestnum"
if [ -e "$TMPFILE" ]; then I=$(cat $TMPFILE); else I="1"; fi

nettest_start() {
    grep -q "/root/bin/nettest" /etc/rc.local
    if [ $? -eq 1 ]; then
        sed -i 's|touch /var/lock/subsys/local|touch /var/lock/subsys/local \&\& /root/bin/nettest|' /etc/rc.local 2>&-
        echo "Script started at $DATEVAL"  >> "$LOGFILE" 2>&1
        echo "Script will run every $TIMELb minutes, $LIMIT times"
        touch "$TMPFILE"
        nettest_run
    else
        echo "Nettest is already started and will relaunch upon next reboot"
    fi

}

nettest_run() {
    echo "$DATE : Starting scan" >> "$LOGFILE" 2>&1
    #

    while [[ "$I" -lt "$LIMIT" ]]
    do
        echo "$DATE : Starting scan" >> "$LOGFILE" 2>&1
        #
        HOSTS="$(...)"


        for myHost in $HOSTS
        do

            PING=$(ping -f -c $COUNT "$myHost" |grep 'rtt' | awk '{print $4}')
            echo "$myHost / $PING" >> "$LOGFILE" 2>&1
        done
        echo "$DATEVAL : Finished" >> "$LOGFILE" 2>&1
        echo "$DATEVAL : Netstat Start" >> "$STATLOG" 2>&1
        netstat -s |egrep -i "dropped|loss|reject|timeout|invalid" >> "$STATLOG" 2>&1
        echo "$DATEVAL : Netstat Finished" >> "$STATLOG"G 2>&1
        echo "." >> "$LOGFILE" 2>&1
        sleep "$TIMEL"
        let I++ || true
        set +C
        echo "$I" > "$TMPFILE"
    done
}

Edit 4: re-added } and showing both functions.

I also need to figure out how to write an exit for the loop, but I'm pretty sure that's just a [ $? = 0 ]

Edit: An example of some of the output I'm seeing when I run a status command (built into the script)..

Nettest is enabled on startup
PID number: 6059
Nettest is actively running in memory
On iteration  of 100

iteration shows 1 on the first run.

Edit 2: redid the sample with full example, minus customized commands.

lurker
  • 56,987
  • 9
  • 69
  • 103
  • You mean it's not writing the count file? Where is `$LIMIT` set and to what value? As long as `$HOSTS` has some values, it would look like this code snippet should work. Did you try executing a simple case like the above code sample to verify the mechanism? Perhaps something else in your actual code is preventing it from working properly. – lurker Dec 30 '14 at 18:26
  • The rest of the code works. Limit works. See the edit to the original post. – Confused Helpdesker Dec 30 '14 at 18:31
  • `echo $I > TMPFILE` is a problem. It needs a dollar sign: `echo $I > $TMPFILE`. And what's the final `}` for? I made a quick script from the snippet you show and it executes the counter file as expected (if I include the corrected dollar sign). – lurker Dec 30 '14 at 18:41
  • the $ was removed when I tried removing the quotes and did one to many deletes. Fixed now, still not working. The whole thing is in a function and that's the end of it. – Confused Helpdesker Dec 30 '14 at 18:46
  • 1
    If you're in a function, you might not have access to the `I` variable, because of scoping. Can you give us the whole function, and the snippet that should print the iteration number? – Spencer Rathbun Dec 30 '14 at 18:49
  • I ran your snippet shown above in a script file and it counts the counter properly as expected. Have you tried that? As @SpencerRathbun is indicating, and what I've said before, it's likely something beyond the sample logic you're showing that's the issue. – lurker Dec 30 '14 at 18:49
  • Functions now included, including the initiating function and the run function. – Confused Helpdesker Dec 30 '14 at 19:01
  • Oh, there it is. You're in a while loop. See [here](http://stackoverflow.com/a/13727116/724357) for a fix for some of it. – Spencer Rathbun Dec 30 '14 at 19:07
  • I kinda see where that's going but seem to lose it about half way. This is only my third full script and first time with writing with functions. – Confused Helpdesker Dec 30 '14 at 19:13
  • Spencer, do you think you could put an example as an answer? – Confused Helpdesker Dec 30 '14 at 19:19
  • @ConfusedHelpdesker, you can use the `@username` syntax to send people you're comment, otherwise they have to stay on the page/be the owner of the thing you've commented on. – Spencer Rathbun Dec 30 '14 at 19:32
  • 1
    Are you aware that `/tmp` is frequently cleaned out on a reboot - sometimes due to that fact that it's a `tmpfs` (memory-based) file system, sometimes because there's an explicit start up script that cleans it out? If you want something to be persistent, don't put it in `/tmp`... – twalberg Dec 30 '14 at 20:51

3 Answers3

1

In the end, I got it working by adding 2>&1 to the line needed.

echo "$I" > "$TMPFILE" 2>&1
0

Try this:

if [ -e "$TMPFILE" ]; then I=`cat $TMPFILE`; else I=1; fi

while [[ $I -lt $LIMIT ]]
AstroCB
  • 12,337
  • 20
  • 57
  • 73
lonewasp
  • 106
  • 3
0

A while loop creates a subshell, with a copy of all your current variables.

#!/bin/bash
I=1
CHECK=1 # boolean for demonstration
while CHECK; do
    let I++
    CHECK=0
done
echo $I # prints 1, not two

This happens because the while subshell gets a copy of the I variable, which it increments. Once the subshell exits, the original variable comes back.

Your I variable is being incremented, and acting as your loop counter. I expect this is causing you all kinds of problems for properly ending your loop, and having other bits of this program see the "right" variable. I see no reason you could not replace the while loop with an equivalent for loop, and avoid all of these problems entirely.

Spencer Rathbun
  • 14,510
  • 6
  • 54
  • 73