Search code examples
linuxbashshellipping

Bash script to ping IP address and report with a datestamp when the station changes ping result in a loop


I started with needing to ping a remote office Cisco Catalyst over my SD/WAN network. Basic ping commands work acceptably well, however the pile of output is both daunting and not very useful. More specifically what I need are date and time stamps of when the remote Catalyst changes its ping state. The date and time when it is unreachable, and the date and time when it becomes reachable again. I don't need any of the ping details, just to know when the UP and DOWN happen. I have a script that I wrote, it didn't work properly, and so I tried to simplify it, and it also didn't work properly. So I turn to you folks, has anyone else tried this with ping?

#!/bin/bash
skip=no
while :
do
    if [[ `ping -c 1 $1 &> /dev/null` ]] && [[ skip = "no" ]]
    then
        echo "Target is up at: $(TZ='America/New_York' date)"
            skip=yes
    else
        echo "Target is down at: $(TZ='America/New_York' date)"
            skip=yes
    fi
    if ping -c 1 $1 &> /dev/null
    then
        skip=no
    else
        skip=yes
    fi
    sleep 5
done

Thanks :)

What I got out of it didn't do what I expected. I have another catalyst locally, I configured that to be 10.1.1.51 on my LAN, and when I have it connected to the rest of the network I get the datestamp and the ping response that it is up, and that behaves fine, and then I unplug it, and in a few moments, I get a another timestamp that it's down. Then another report that it's down, and another, and another. I think it's an edge case and the fault I think is in my if-then-else-fi logic, but I've tried many other arrangements and either the "Ping success" message repeats, or the "Ping Failure" messge repeats, but not the way I want, which is just report when the state changes and otherwise just sit there testing and pinging and waiting for the state to change. It's been years since I did anything like this, heh, necessity is the mother of invention, I guess. :)


Solution

  • I asked around on Mastodon and someone posted this as a solution. It works just like I wanted it to. So my original effort was rubbish and is off to the big bit bucket in the sky.

    Here's the script, it works, I'm walkin away.

    #!/bin/bash
    TZ='America/New_York'
    export TZ
    ping  -i 5 "$1" 2>&1 | awk '/Host/{ state="Down" } /time/{ state="Up" } prev_state!=state{prev_state=state; print strftime(), host, state}' host=$1;