20

I'm writing a wake on lan script for a set of our lab computers. We have sqlite db with a list of the computer hostnames, IPs, and MACs and currently I ping each of them with '-c1' so it doesn't run endlessly - but even that takes some waiting, is there a quicker way to get answer rather than ping? Using ping seems to slow the script quite a bit as it needs the ping answers to continue.

Thanks much for any suggestions!

8 Answers 8

21

Sending a single packet and waiting for a response is going to be one of the fastest possible ways, and ping is a fine way to do that. In fact, depending on your use case, I'd argue that it's too fast, since it doesn't really tell you if the system is actually doing anything useful, just that the kernel's network subsystem is alive and configured.

But assuming that's good enough, you can make some improvements. First, you could use -W1 to decrease the ping timeout to one second. Second, you could make your script ping the different hosts asynchronously (in a background thread), and check the results as needed rather than waiting.

Alternately, you can re-think the approach and have the remote systems check in somehow when they're up, and if a system hasn't checked in, you can assume it's down.

6
  • Good call on the -w addition, had to make it two though cause a bunch of computers didn't respond quick enough. Might look into adding some sort of periodic check-in as well or hand-shake but for now want to have the process relatively external to the computers I'm turning on.
    – Jon Phenow
    Feb 17, 2011 at 16:00
  • 1
    I also use -s to send a smaller packet. Feb 17, 2011 at 17:18
  • 3
    I'll be shocked if sending a smaller packet makes a difference.
    – mattdm
    Feb 17, 2011 at 17:24
  • Aren't they pretty much already sent at near minimum size of packets?
    – Jon Phenow
    Feb 17, 2011 at 19:16
  • 4
    They're pretty small; there's a default of 56 data bytes, which you could reduce. But in any case, it's smaller than the ethernet MTU and bigger than nothing, so it comes down to "one packet" either way.
    – mattdm
    Feb 17, 2011 at 19:29
7

This is what fping was designed for. http://fping.sourceforge.net/

You need to parse the output afterwards instead of relying on a return code, but it is much faster than doing normal ping.

2
  • I think it's kinda funny the description says "Unlike ping, fping is meant to be used in scripts and its output is easy to parse." and yet it doesn't provide a return code Apr 27, 2018 at 21:07
  • What would good values be for the return code? Apr 27, 2018 at 21:33
3

This would only work for one or two computers, but if you connect them directly to the computer responsible for checking their status, you can use ethtool to see if the link is active or not.

2
  • I have not used ethtool for this, would you like to give a example? (or maybe a link)?
    – Johan
    Feb 18, 2011 at 7:17
  • ethtool {network_interface} | grep "Link detected" | cut -f 3 -d ' ' will return yes if a machine is connected, and no if it is not.
    – LawrenceC
    Feb 21, 2011 at 17:04
2

What you could do it ping the broadcast address which should cause all the computers to ping back. Then you could cross check this list against what you have in SQLite to ensure all the computers are up.

Other then that a ping is probably the fastest way to ensure a computer is awake on a network. As mentioned by the other answer this doesn't provide any really useful data. If you have the ability to install scripts you can add a cronjob to ping a central server, run a task, or just echo out the process list to a central server which will log the request. Then simply checking that will tell you if you have any issues with no need to manually check every time.

4
  • 1
    I assume you mean ping the broadcast address, not the gateway. On modern systems, that probably won't work. See unix.stackexchange.com/questions/7458/cant-ping-broadcast
    – mattdm
    Feb 17, 2011 at 15:25
  • 1
    @mattdm: Multicast then? I wasn't aware most people turned it off. I haven't had encountered issues with it before.
    – Josh K
    Feb 17, 2011 at 15:31
  • Haha yes thanks mattdm, a similar problem you can see I ran into. its not that people turn them off but they generally come with broadcast off lately apparently.
    – Jon Phenow
    Feb 17, 2011 at 15:34
  • Could use fping (fping.sourceforge.net) to ping a list of hosts in parallel. Then you don't have to rely on being able to ping the broadcast address.
    – mazianni
    Feb 17, 2011 at 18:31
2

Ganglia uses multicast traffic to monitor many hosts in a cluster, perhaps you could use something similar? This assumes that your networking hardware allows multicast traffic between all the hosts and your monitoring system.

1
  • 1
    Looks like a cool tool but for the purposes of this little script might add some unnecessary chunk to the project, keepin' it as a pretty small script for now. Will definitely keep my eye on it though, looks like a tool I might use soon non-the-less.
    – Jon Phenow
    Feb 17, 2011 at 16:01
0

I had the same problem and came up with the following (quick & dirty) script. This esentially issues all pings as separate jobs in parallel and will scan an an entire /24 subnet in 3 seconds; note that for some reason I did not bother to find out I could not use the ping result code here but grep -v did the job:

#!/bin/bash
case $# in
1)
  case $1 in
  [1-9]*)
        echo
        echo Systems active in subnet: $1
        for (( K = 1 ; K < 255 ; K=$K+1 )); do
        # grep -v delivers 0 on no matches
                echo -ne "testing:" $1$K "...    \r"
                (if ping -c 1 -w 1 -n $1$K 2>&1 | grep -q '64 bytes' ; then
                echo $1$K alive "                "
                fi) &
        done
        sleep 3
        echo "                               "
        exit 0
        ;;
  esac;;
esac
0

In C,

/* count = 1, wait interval = 1 second, no name lookup, */
/* 10 data bytes, 1 second timeout, 200 millisecond wait time */

sprintf(command,"ping -c1 -i1 -n -s10 -t1 -W200 %u" 
   , connection[port].IPAddress);
err = system(command);
/* err == 0 means OK */
0

I've found fping -r0 ... to provide the fastest response.

The -r (retry) option seems faster than the similar -c (count). Using -r0 results in just one ping being sent and the output is much abbreviated compared to other options.

On my system...

fping -r0 PRINTER LX00 LX01 LX02 LX03 HA01  2>&1

Results in...

LX00 is alive
LX02 is alive
HA01 is alive
ICMP Host Unreachable from 192.168.1.5 for ICMP Echo sent to LX01
PRINTER is unreachable
LX01 is unreachable
LX03 is unreachable

A little massaging to get rid of the ICMP message(s) gives me...

fping -r0 PRINTER LX00 LX01 LX02 LX03 HA01  2>&1 | grep ' is ' | sort

HA01 is alive
LX00 is alive
LX01 is unreachable
LX02 is alive
LX03 is unreachable
PRINTER is unreachable

As for speed, the fping on this old 1.8GHz Intel Dual-Core with 4GB RAM is...

time fping -r0 PRINTER LX00 LX01 LX02 LX03 HA01 2>&1

LX00 is alive
LX02 is alive
HA01 is alive
PRINTER is unreachable
LX01 is unreachable
LX03 is unreachable

real    0m0.554s
user    0m0.000s
sys     0m0.000s

And the grep and sort seem to only add 0.001-0.004s to the time...

time fping -r0 PRINTER LX00 LX01 LX02 LX03 HA01 2>&1 | grep ' is ' | sort

HA01 is alive
LX00 is alive
LX01 is unreachable
LX02 is alive
LX03 is unreachable
PRINTER is unreachable

real    0m0.558s
user    0m0.000s
sys     0m0.000s

NOTES

  • The ICMP message doesn't occur on every run.
  • The 2>&1 is necessary to prevent the ICMP message from showing up in the output as it is sent to stderr instead of stdout.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .