Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

This script scans IP's and returns a status of Up or Down. How can I alter it so it doesn't scan everything twice? As it sits it scans everything and returns the "Up" addresses only and then scans all over again and only returns the "Down" status addresses.


  ping -c 1 $1 > /dev/null
  [ $? -eq 0 ] && echo $i,Up
  [ $? -eq 1 ] && echo $i,Down

for i in 10.1.150.{1..10}
is_alive_ping $i & disown

Bonus points if anyone can make it also return the DNS name of the IP if it has one.

Thanks in advance.

share|improve this question
up vote 1 down vote accepted

The script scans each IP just once. The scanning is happening in the background (&). The down IP's take longer time to respond, that's why they are reported later.

share|improve this answer
Duh. thanks. Need my coffee ;) – LVLAaron Jan 3 '12 at 16:16
where is background stuff here in shell? I guess am puzzled. Its different ping is unable to get the answer from the offline nodes and is reporting them at the end after minimal default retries. – Nikhil Mulley Jan 3 '12 at 16:21
@Nikhil: the function is called with & (as I also mentioned): background subshell. – choroba Jan 3 '12 at 16:27

You're looking for nmap.

# nmap -sP
Starting Nmap 5.00 ( http://nmap.org ) at 2012-01-04 00:02 CET
Host foo.example.com ( is up (0.00066s latency).
Host bar.example.com ( is up (0.00066s latency).
Nmap done: 10 IP addresses (1 host up) scanned in 1.41 seconds
share|improve this answer

ping retries for unanswering nodes, which adds to the latency in reporting the availability of the nodes back to the console output, while the answered online nodes are reported immediately back. ping has this disadvantage that you need to execute it for every host.

Use fping, a better alternative to ping , which can do a parallel ping on the hosts, source is available at sourceforge http://fping.sourceforge.net/ . Download fping and install it under /usr/local/sbin and make it suid.

Here is a perl example, that can report the unreachable nodes at the end, while the nodes that are online are reported with their dns names, you can pass the output of this script to tools such as grep or awk again to work on the desired output.

require 'open2.pl';
use Net::IP;

$pid = &open2("OUTPUT","INPUT","/usr/local/sbin/fping -d");


my $ip = new Net::IP (' -') || die "Unable to generate range\n";

do {
    push (@check, $ip->ip());
} while (++$ip);

foreach(@check) { print INPUT "$_\n"; }


while(<OUTPUT>) {
  print "$_";

share|improve this answer

If you want to keep the order you have to redirect the output not to stdout, but to files. After all pings are done, do a wait to wait for the last background process to finish. Then cat the result files in the "right" order.

share|improve this answer

adding -w to ping will allow the process to be much quicker.


  ping -c 1 -w 1 $1 > /dev/null
  [ $? -eq 0 ] && echo $i ,Alive

for i in 192.168.213.{1..254}
is_alive_ping $i &
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.