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 a range of IP addresses as input.
Some machines don't answer pings (e.g. firewalls).
If you only want the local network you can use this command:
(for n in $(seq 1 254);do sudo arping -c1 10.0.0.$n & done ; wait) | grep reply | grep --color -E '([0-9]+\.){3}[0-9]+'
arping
is a command that sends ARP requests. It is present on most of linux. Example:
sudo arping -c1 10.0.0.14
the sudo is not necessary if you are root ofc.
10.0.0.14
: the ip you want to test-c1
: send only one request.&
: the 'I-don't-want-to-wait' characterThis is a really useful character that give you the possibility to launch a command in a sub-process without waiting him to finish (like a thread)
for
loop is here to arping all 255 ip addresses. It uses the seq
command to list all numbers.wait
: after we launched our requests we want to see if there are some replies. To do so we just put wait
after the loop.
wait
looks like the function join()
in other languages.()
: parenthesis are here to interpret all outputs as text so we can give it to grep
grep
: we only want to see replies. the second grep is just here to highlight IPs.hth
The bad part of my solution is that it print all results at the end. It is because grep have a big enough buffer to put some lines inside.
the solution is to add --line-buffered
to the first grep.
like so:
(for n in $(seq 1 254);do sudo arping -c1 10.0.0.$n & done ; wait) | grep --line-buffered reply | grep --color -E '([0-9]+\.){3}[0-9]+'
In the real world, you could use nmap to get what you want.
nmap -sn 10.1.1.1-255
This 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.
#!/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
There is also fping:
fping -g 192.168.1.0/24
or:
fping -g 192.168.1.0 192.168.1.255
or show only hosts that are alive:
fping -ag 192.168.1.0/24
It pings hosts in parallel so the scan is very fast. I don't know a distribution which includes fping
in its default installation but in most distributions you can get it through the package manager.