2

Alright so I need to constantly monitor multiple routers and computers, to make sure they remain online. I have found a great script here that will notify me via growl(so i can get instant notifications on my phone) if a single ip cannot be pinged. I have been attempting to modify the script to ping multiple addresses, with little luck. I'm having trouble trying to figure out how to ping a down server while the script keeps watching the online servers. any help would be greatly appreciated. I haven't done much shell scripting so this is quite new to me.

Thanks

#!/bin/sh

#Growl my Router alive!
#2010 by zionthelion73 [at] gmail . com
#use it for free
#redistribute or modify but keep these comments
#not for commercial purposes

iconpath="/path/to/router/icon/file/internet.png"
# path must be absolute or in "./path" form but relative to growlnotify position
# document icon is used, not document content

# Put the IP address of your router here
localip=192.168.1.1

clear
echo 'Router avaiability notification with Growl'

#variable
avaiable=false

com="################"
#comment prefix for logging porpouse

while true;
do
if $avaiable
then
  echo "$com 1) $localip avaiable $com"
  echo "1"
  while ping -c 1 -t 2 $localip
    do
      sleep 5
    done
  growlnotify  -s -I $iconpath -m "$localip is offline"
  avaiable=false
else
  echo "$com 2) $localip not avaiable $com"
  #try to ping the router untill it come back and notify it
  while !(ping -c 1 -t 2 $localip)
  do
   echo "$com trying.... $com"
   sleep 5
  done

  echo "$com found $localip $com"
  growlnotify -s -I $iconpath -m "$localip is online"
  avaiable=true
fi

sleep 5

done
Alex
  • 53
  • 1
  • 5

4 Answers4

2

I don't think it's necessary to run multiple scripts. Here is a general script to monitor a list of IP addresses and note changes in ping success...

#!/bin/bash
set 10.0.0.1 10.0.0.2 # etc
trap exit 2
while true; do
  i=1
  for ipnumber in "$@"; do
    statusname=up$i
    laststatus=${!statusname:-0}
    ping -c 1 -t 2 $ipnumber > /dev/null
    ok=$?
    eval $statusname=$ok
    if [ ${!statusname} -ne $laststatus ]; then
      echo status changed for $ipnumber
      if [ $ok -eq 0 ]; then
        echo now it is up
      else
        echo now it is down
      fi
    fi
    i=$(($i + 1))
  done
  sleep 5
done
DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
  • thanks, but i need to know is its online on offline not if it just changed from one status to another. will multiple script cause a significant increase in resource usage? – Alex Jan 16 '11 at 23:42
  • See my answer for a similar technique using arrays. – Dennis Williamson Jan 16 '11 at 23:45
  • @Alex: OK, ok, I've modified the script so you can see how to check up or down. But at some point you are just going to have to read "man bash". The problem with running multiple scripts in the background isn't resource consumption but complexity. It's ugly, they will be annoying to check and to kill, you can't easily log their output, it's hard to debug, etc etc. – DigitalRoss Jan 16 '11 at 23:55
  • wow that's great, thanks a lot. although I cant figure out how to verify ONLINE ip's as well as OFFLINE ip's on start up. it just displays the ones the are offline. until it becomes offline first it will not display that it is online. – Alex Jan 17 '11 at 00:35
  • Alright this might be asking to much, but i also want to ass along ip names(i.e router basement, pc 1, ect). I think i might just stick with multiple scripts if its to difficult. thanks again – Alex Jan 17 '11 at 00:44
1

The simplest approach is to wrap this script with another one that creates N processes. Assume your script is called "watchip", then put into another script the text

watchip 10.0.1.1 &
watchip 10.0.1.2 &
watchip 10.0.1.3 &
etc

and set localip to $1 inside watchip.

Martin v. Löwis
  • 124,830
  • 17
  • 198
  • 235
0

Change localip=192.168.1.1 to:

localip=$1

This allows the IP address to be passed in as a command-line argument. Then you can run multiple copies of the script passing in different IP addresses. You could then create a master script to run multiple copies of the monitoring script. Assuming the script you posted is monitor.sh:

#!/bin/sh

monitor.sh 192.168.1.1 &
monitor.sh 192.168.2.2 &
monitor.sh 192.168.3.3 &
wait
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
0

Keep two arrays. One with available IPs; the other with unavailable ones. When their status changes, move them to the other array. No need for multiple background processes.

I've omitted the logging stuff. You can add it back in. This is untested code.

available=(192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4)
unavailable=()

while true
do
    for index in ${!available[@]}
    do
        if ! ping -c 1 -t 2 ${available[index]}
        then
            growlnotify  -s -I $iconpath -m "${available[index]} is offline"
            unavailable+=(${available[index]})
            unset "available[index]"
        fi
    done

    for index in ${!unavailable[@]}
    do
        if ping -c 1 -t 2 ${unavailable[index]}
        then
            growlnotify  -s -I $iconpath -m "${unavailable[index]} is back online"
            available+=(${unavailable[index]})
            unset "unavailable[index]"
        fi
    done
done
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • I'm not sure what is going on, no notifications it just stops, after the second ping with the output: "Enter a notification description, followed by newline, followed by Ctrl-D (End of File). To cancel, press Ctrl-C." – Alex Jan 16 '11 at 23:55
  • @Alex: That's probably because I didn't include some of the code from your original. In addition to the logging-related code, I didn't set the variable `iconpath` which is likely causing the error. Also, you may want to redirect the output of `ping`: `ping ... > /dev/null`. – Dennis Williamson Jan 17 '11 at 00:00