Quick PERL or BASH script that can ping a large number of devices simultaneously

Hi Team,

   Can I just solicit some PERL or BASH code from you experts that would allow a script to ping multiple devices simultaneously  (i.e. spawning multiple bash PING instances)   and then just display the output to screen of which were successful or not?

For example,  I am looking for something very simple like sending a salvo of 10 pings (and because of ARP aging), if I get 6 or more pings back, then say UP, 0 means down, and 1-5  means VERIFY:

./ping-network-nodes   devicelist.txt

Open in new window


And them my devicelist.txt would have something like

Router1, 10.10.1.1
Router2,10.10.1.2
Firewall1,10.10.5.1
Firewall2,10.10.5.2
server1,10.10.3.1
server2,10.10.3.2

After which I just get an output on screen with:

Router1  -  UP - 6/10 pings
Router2, - DOWN - 0/10 pings
Firewall1 - DOWN - 0/10  pings
Firewall2 - UP  - 8/10 pings
server1  - VERIFY - 2/10 pings
server2, - VERIFY - 1/10 pings

Open in new window


My final list would be 70 - 100 devices long , but I show the above as sample only.  And I don't mind if the script writes to 70 - 100 individual small files where it writes its temporary output,   as long as it can clean it up after.   thanks.

Thanks very much.
rleyba828Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

rleyba828Author Commented:
Also....can I do something like:

./ping-network-nodes   devicelist.txt | grep DOWN

Open in new window


so I can filter the output?

Thanks again.
gheistCommented:
You can feed list of hosts to nmap and get CSVoutput.
rleyba828Author Commented:
Thanks gheist,

  While that may work,   I was specifically looking for a script so that we have more granular control over what we want the program to do.

Thanks
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

gheistCommented:
I dont see the difference in ping being suid root and nmap ran as root in regard of "what program can do"
rleyba828Author Commented:
There will be a difference as I have other things in mind with regard to granular control.....for example, interval between pings,   number of pings per host, retries if failed,   time stamps, and many other things I will eventually need to use in this script and other subsequent scripts that would communicate with this one....and I want to be able to program these things.

My original question remains....."looking for a bash script that can simultaneously spawn multiple pings at once to different hosts and write output to a file...."

Thanks
gheistCommented:
nmap sends multiple icmp packets and waits for replies without spawns.
bash script is not the right thing to format CSV files when you have excel.
FishMongerCommented:
Using nmap as gheist suggests would normally be my first recommendation as well, if there wasn't the need/want to do the pings simultaneously.

If you want to do this with a perl script, then you'll want to use the Net::Ping and Parallel::ForkManager modules and I'd also recommend adding in Getopt::Long and Pod::Usage.

Additional modules may need to be used depending on what is involved with the many other (unspecified) things you say this script needs to do.
rleyba828Author Commented:
Hi Fishmonger,

    Yes, this is a good start.......  I will have to read through the Parallel::ForkManager  documentation to understand how that works.

To All,
   I have previously used the SCREEN function in Linux where I can login to another sort of  bash session and run commands there independently of my parent session.  I wonder if I can use that to spawn the 70 to 100 simultaneous pings I can do and have them all write to their own respective output files and I'll just have another script that parses through the outputs.

thanks.
FishMongerCommented:
Wanting to use multiple screen sessions for this doesn't make any sense.
rleyba828Author Commented:
Hi Fishmonger,  can you kindly explain why it would not make sense?   when I do remote troubleshooting to try to catch transients in my network I normally spawn multiple SCREEN sessions simultaneously with each SCREEN session pinging a different host.     I have the output of the pings logging to syslog and after several days I can look at the syslog logfile and see if there have been any dropped pings from any of the multiple screen sessions running concurrently.

The only downside to that is that it is a manual approach and I have to kill the screen sessions one by one, and if I have to do this for  5 sessions  (corresponding to 5 different hosts) it becomes unwieldy to handle without a script.

thanks
skullnobrainsCommented:
simple and with less feature
sed -e ' s/.*/if ping -c 10 -v -w 3 & ; then echo &,UP ; else echo &,down/' << HOSTSLIST | sh

more complex (reads host list from stdin)

#!/bin/sh

parallel=5
num=10
wait=`expr $num + 2`
tresh_vrfy=2

if test -n "$1"
then xargs -P $parallel -n1 $0 << /dev/stdin
          exit $?
fi

rcvd=$(expr "`ping -c $num -v -w $wait $1`" : '.* \([0-9]*\) received')

test "$rcvd" = 0 && echo $1  - DOWN - $rcvd/$num PINGS && exit 1
test "$rcvd" -le $tresh_vrfy && echo $1  - VERIFY - $rcvd/$num PINGS && exit 0
test "$rcvd" -ge 0 && echo $1  - UP - $rcvd/$num PINGS && exit 0
echo $1  - TEST FAILED - $rcvd/$num PINGS && exit 2
FishMongerCommented:
Using multiple screen sessions is "ok" when done on a limited basis in a manual environment but not when you want to automate the process or you need to scale up.  To connect via screen, the remote system must already have a user logged-in with an active terminal window.  That can not be relied upon when using an automated tool.  It would make more sense if the automated tool made ssh connections instead of screen connections.

I'm no longer in the group that does our server monitoring, but our company has over 1,000 servers (plus other network devices) which we need to monitor on a 24/7 basis, and that would be impractical at the least and probably impossible to do using the approach you're thinking about.

Instead of reinventing the wheel, like you're proposing to do, it would be better to use one of the open source tools already designed for this purpose.  We use Nagios for this type of monitoring.  It not only does live monitoring of network reach ability, but also server services and disc space.  It dynamically updates a web page with any/all issues and can send these alerts to specific users/groups via email and/or text messages.
FishMongerCommented:
As an example, here's 1 nagios email alert I often receive.

***** Nagios *****

Notification Type: PROBLEM

Service: Check EDI/Templar Locks
Host: edi
Address: x.x.x.x
State: CRITICAL

Date/Time: Sat Sept 12 11:47:53 PDT 2015

Additional Info:

CRITICAL: EDI has 401 locked files, edi Templar service is possibly frozen!

---------------------------------------------------------------------------------------------------------
rleyba828Author Commented:
Hi fishmonger,

Yes, you are right.....the screen utility does need a user to login and doesn't lend itself to being "automatable" this way.  I have used nagios before and have seen its capabilities, thanks for that.
rleyba828Author Commented:
Hi skullnobrains

somehow, I can't get either of your scripts to work.

the first one:

[root@test]# sed -e ' s/.*/if ping -c 10 -v -w 3 & ; then echo &,UP ; else echo &,down/' << HOSTSLIST | sh
>

Open in new window


* It has the > symbol as though it is waiting for user input.   but I did supply an input file

my HOSTLIST file has these entries:
10.10.2.1
10.10.2.2

As for the 2nd script:

[root@test]# ./pinghosts 10.10.1.2 10.10.1.1
./pinghosts: line 19: warning: here-document at line 9 delimited by end-of-file (wanted `/dev/stdin')
./pinghosts: line 20: syntax error: unexpected end of file

Open in new window



pinghosts file looks like this

[root@test]# cat pinghosts
#!/bin/sh

parallel=5
num=10
wait=`expr $num + 2`
tresh_vrfy=2

if test -n "$1"
then xargs -P $parallel -n1 $0 << /dev/stdin
          exit $?
fi

rcvd=$(expr "`ping -c $num -v -w $wait $1`" : '.* \([0-9]*\) received')

test "$rcvd" = 0 && echo $1  - DOWN - $rcvd/$num PINGS && exit 1
test "$rcvd" -le $tresh_vrfy && echo $1  - VERIFY - $rcvd/$num PINGS && exit 0
test "$rcvd" -ge 0 && echo $1  - UP - $rcvd/$num PINGS && exit 0
echo $1  - TEST FAILED - $rcvd/$num PINGS && exit 2 

Open in new window


Any help would be appreciated.  thanks.
skullnobrainsCommented:
sorry, i typed directly in the screen since i was not in front of a box

here is the first

root@mx85:/opt/pmx6# sed -e ' s/.*/if ping -c 1 -v -w 3 &>\/dev\/null ; then echo &,UP ; else echo &,down ; fi/'  << HOSTSLIST | sh
> 127.0.0.1
> 127.0.0.2
> 8.8.8.8
> 9.9.9.9
> HOSTSLIST
127.0.0.1,UP
127.0.0.2,UP
8.8.8.8,UP
9.9.9.9,down

Open in new window


my example used the heredoc syntax which feeds whever stands between
<<HOSTSLIST
...
HOSTSLIST
to the command's standard input as i it were a file

anything below the HOSTSLIST line is the answer that my box returned ( all ok except for 9.9.9.9)

i edited so ping's output are hidden and only a single ping is sent.
skullnobrainsCommented:
second script corrected a few typos : mainly <<stdin changed to <stdin and -n to -z

#!/bin/sh

parallel=5
num=10
wait=`expr $num + 2`
tresh_vrfy=2

if test -z "$1"
then xargs -P $parallel -n1 sh $0 < /dev/stdin
          exit $?
fi

rcvd=$(expr "`ping -c $num -v -w $wait $1`" : '.* \([0-9]*\) received')

# echo RCVD=$rcvd

test "$rcvd" = 0 && echo $1  - DOWN - $rcvd/$num PINGS && exit 1
test "$rcvd" -le $tresh_vrfy && echo $1  - VERIFY - $rcvd/$num PINGS && exit 0
test "$rcvd" -ge 0 && echo $1  - UP - $rcvd/$num PINGS && exit 0
echo $1  - TEST FAILED - $rcvd/$num PINGS && exit 2

Open in new window


working test.
i'm feeding the liust of ips using printf but you can use a file as well


root@mx85:/opt/pmx6# printf '127.0.0.1\n127.0.0.2\n8.8.8.8\n9.9.9.9\n' | sh /tmp/x
127.0.0.1 - UP - 10/10 PINGS
127.0.0.2 - UP - 10/10 PINGS
8.8.8.8 - UP - 10/10 PINGS
9.9.9.9 - DOWN - 0/10 PINGS

you'd call the script using

sh /path/to/script </path/to/file/with/list/of/ips

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Shell Scripting

From novice to tech pro — start learning today.