How can I write a linux bash script, that tells me which computers are ON in my LAN ?
It would help if I could give it as input a range of IP's.
-
If you're limiting yourself to only having the last octet changing, this script should do it. It should be fairly obvious how to extend it from one to multiple octets.
#! /bin/bash BASE=$1 START=$2 END=$3 counter=$START while [ $counter -le $END ] do ip=$BASE.$counter if ping -qc 2 $ip then echo "$ip responds" fi counter=$(( $counter + 1 )) doneshodanex : This just to long !! -
Assuming my network is 10.10.0.0/24, if i run a ping on the broadcast address like
ping -b 10.10.0.255I'll get an answer from all computers on this network that did not block their ICMP ping port.
64 bytes from 10.10.0.6: icmp_seq=1 ttl=64 time=0.000 ms 64 bytes from 10.10.0.12: icmp_seq=1 ttl=64 time=0.000 ms 64 bytes from 10.10.0.71: icmp_seq=1 ttl=255 time=0.000 msSo you just have to extract the 4th column, with awk for example:
ping -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }' 10.10.0.12: 10.10.0.6: 10.10.0.71: 10.10.0.95:Well, you will get duplicate, and you may need to remove the ':'.
EDIT from comments : the -c option limits the number of pings since the script will end, we can also limit ourself on unique IPs
ping -c 5 -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }' | sort | uniqBen : ping -b 10.10.0.255 | awk '{ print $4 }' | sort | uniq will remove the duplicatesJochen Walter : @Ben: You should add the -c option in the call to ping, because otherwise it won't terminate.shodanex : It does not work for me, but the nmap solution doeschburd : the -b option is not present for all pings. for example it is OK on my OpenSuse, but not on my Mac, you still can try without this option -
In the real world, you could use nmap to get what you want.
nmap -sP 10.1.1.1-255This will ping all the addresses in the range 10.1.1.1 to 10.1.1.255 and let you know which ones answer.
Of course, if you in fact want to do this as a bash exercise, you could run ping for each address and parse the output, but that's a whole other story.
-
Also using the "ping the broadcast address" method pointed out by chburd, this pipe should do the trick for you:
ping -c 5 -b 10.11.255.255 | sed -n 's/.* \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p' | sort | uniqOf course, you'd have to change the broadcast address to that of your network.
-
Just for fun, here's an alternate
#!/bin/bash nmap -sP 192.168.1.0/24 > /dev/null 2>&1 && arp -an | grep -v incomplete | awk '{print$2}' | sed -e s,\(,, | sed -e s,\),,hlovdal : You can combine <> into just < > Eddy : Cool, thanks for the hint -
Kalmi : "ip neighbor" and "arp -a" won't show machines with which you have not communicated for a while (or at all)
-
As other posters pointed out,
nmapis the way to go, but here's how to do the equivalent of a ping scan in bash. I wouldn't use the broadcast ping, as a lot of systems are configured not to respond to broadcast ICMP nowadays.for i in $(seq 1 254); do host="192.168.100.$i" ping -c 1 -W 1 $host &> /dev/null echo -n "Host $host is " test $? -eq 0 && echo "up" || echo "down" done -
There is also fping:
fping -g 192.168.1.0/24or:
fping -g 192.168.1.0 192.168.1.255or show only hosts that are alive:
fping -ag 192.168.1.0/24It pings hosts in parallel so the scan is very fast. I don't know a distribution which includes
fpingin its default installation but in most distributions you can get it through the package manager. -
I would suggest using nmap's ping-scan flag,
$ nmap -sP 192.168.1.60-70 Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2009-04-09 20:13 BST Host machine1.home (192.168.1.64) appears to be up. Host machine2.home (192.168.1.65) appears to be up. Nmap finished: 11 IP addresses (2 hosts up) scanned in 0.235 secondsThat said, if you want to write it yourself (which is fair enough), this is how I would do it:
for ip in 192.168.1.{1..10}; do ping -t 1 $ip > /dev/null && echo "${ip} is up"; done..and an explanation of each bit of the above command:
Generating list of IP addresses
You can use the
{1..10}syntax to generate a list of numbers, for example..$ echo {1..10} 1 2 3 4 5 6 7 8 9 10(it's also useful for things like
mkdir {dir1,dir2}/{sub1,sub2}- which makesdir1anddir2, each containingsub1andsub2)So, to generate a list of IP's, we'd do something like
$ echo 192.168.1.{1..10} 192.168.1.1 192.168.1.2 [...] 192.168.1.10Loops
To loop over something in bash, you use
for:$ for thingy in 1 2 3; do echo $thingy; done 1 2 3Pinging
Next, to ping.. The ping command varies a bit with different operating-systems, different distributions/versions (I'm using OS X currently)
By default (again, on the OS X version of
ping) it will ping until interrupted, which isn't going to work for this, soping -c 1will only try sending one packet, which should be enough to determine if a machine is up.Another problem is the timeout value, which seems to be 11 seconds on this version of ping.. It's changed using the
-tflag. One second should be enough to see if a machine on the local network is alive or not.So, the ping command we'll use is..
$ ping -c 1 -t 1 192.168.1.1 PING 192.168.1.1 (192.168.1.1): 56 data bytes --- 192.168.1.1 ping statistics --- 1 packets transmitted, 0 packets received, 100% packet lossChecking ping result
Next, we need to know if the machine replied or not..
We can use the
&&operator to run a command if the first succeeds, for example:$ echo && echo "It works" It works $ nonexistantcommand && echo "This should not echo" -bash: nonexistantcommand: command not foundGood, so we can do..
ping -c 1 -t 1 192.168.1.1 && echo "192.168.1.1 is up!"
The other way would be to use the exit code from ping.. The ping command will exit with exit-code 0 (success) if it worked, and a non-zero code if it failed. In bash you get the last commands exit code with the variable
$?So, to check if the command worked, we'd do..
ping -c 1 -t 1 192.168.1.1; if [ $? -eq 0 ]; then echo "192.168.1.1 is up"; else echo "ip is down"; fiHiding ping output
Last thing, we don't need to see the ping output, so we can redirect
stdoutto/dev/nullwith the>redirection, for example:$ ping -c 1 -t 1 192.168.1.1 > /dev/null && echo "IP is up" IP is upAnd to redirect
stderr(to discard theping: sendto: Host is downmessages), you use2>- for example:$ errorcausingcommand -bash: errorcausingcommand: command not found $ errorcausingcommand 2> /dev/null $The script
So, to combine all that..
for ip in 192.168.1.{1..10}; do # for loop and the {} operator ping -c 1 -t 1 192.168.1.1 > /dev/null 2> /dev/null # ping and discard output if [ $? -eq 0 ]; then # check the exit code echo "${ip} is up" # display the output # you could send this to a log file by using the >>pinglog.txt redirect else echo "${ip} is down" fi doneOr, using the
&&method, in a one-liner:for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; doneProblem
It's slow.. Each ping command takes about 1 second (since we set the -t timeout flag to 1 second). It can only run one ping command at a time.. The obvious way around this is to use threads, so you can run concurrent commands, but that's beyond what you should use bash for..
"Python threads - a first example" explains how to use the Python threading module to write a multi-threaded ping'er.. Although at that point, I would once again suggest using
nmap -sP..Ash Kim : *** slow clap ***CodeJoust : Is there a way to create and initiate threads in BASH? This probably could be done in ruby/python as a script just opening an Network connection, but could the same ability to create multiple threads can be done in BASH?dbr : You could run the process in the background the command by doing `mycmd &`, but that's not really threading, and could become quite complicated if you need the output of several commands.. It would be much simpler to just use Python/Ruby/etc.. -
please try this,,,more faster,,,tnks for all,,,
!/bin/bash
for ((n=0 ; n < 30 ; n+=1)) do ip=10.1.1.$n if ping -c 1 -w 1 $ip > /dev/null 2> /dev/null >> /etc/logping.txt; then
echo "${ip} is up" # output klien up # sintax >> /etc/logping.txt to create log with .txt format else echo "${ip} is down" # output klien downfi done
-
#!/bin/bash for ((n=0 ; n < 30 ; n+=1)) do ip=10.1.1.$n if ping -c 1 -w 1 $ip > /dev/null 2> /dev/null >> /etc/logping.txt; then echo "${ip} is up" # output up # sintax >> /etc/logping.txt log with .txt format else echo "${ip} is down" # output down fi done -
#!/bin/bash #Get the ip address for the range ip=$(/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}' | cut -d"." -f1,2,3) # ping test and list the hosts and echo the info for range in $ip ; do [ $? -eq 0 ] && ping -c 1 -w 1 $range > /dev/null 2> /dev/null && echo "Node $range is up" done
0 comments:
Post a Comment