Ich würde vorschlagen, das Ping-Scan-Flag von nmap zu verwenden,
$ nmap -sn 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 seconds
Das heißt, wenn Sie es selbst schreiben möchten (was fair genug ist), würde ich es so machen:
for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done
..und eine Erklärung für jedes Bit des obigen Befehls:
Erzeuge Liste von IP-Adressen
Sie können den {1..10}
verwenden Syntax zum Generieren einer Liste von Zahlen, zum Beispiel..
$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
(Es ist auch nützlich für Dinge wie mkdir {dir1,dir2}/{sub1,sub2}
- was dir1
ergibt und dir2
, die jeweils sub1
enthalten und sub2
)
Um also eine Liste von IPs zu erstellen, würden wir so etwas tun wie
$ echo 192.168.1.{1..10}
192.168.1.1 192.168.1.2 [...] 192.168.1.10
Schleifen
Um etwas in Bash zu durchlaufen, verwenden Sie for
:
$ for thingy in 1 2 3; do echo $thingy; done
1
2
3
Ping
Als nächstes zu Ping. Der Ping-Befehl variiert ein wenig mit verschiedenen Betriebssystemen, verschiedenen Distributionen/Versionen (ich verwende derzeit OS X)
Standardmäßig (wiederum in der OS X-Version von ping
) wird es pingen, bis es unterbrochen wird, was dafür nicht funktionieren wird, also ping -c 1
wird nur versuchen, ein Paket zu senden, was ausreichen sollte, um festzustellen, ob eine Maschine aktiv ist.
Ein weiteres Problem ist der Timeout-Wert, der bei dieser Version von Ping 11 Sekunden zu sein scheint. Er wird mit -t
geändert Flagge. Eine Sekunde sollte ausreichen, um zu sehen, ob eine Maschine im lokalen Netzwerk aktiv ist oder nicht.
Der Ping-Befehl, den wir verwenden werden, ist also..
$ 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 loss
Ping-Ergebnis prüfen
Als nächstes müssen wir wissen, ob die Maschine geantwortet hat oder nicht..
Wir können den &&
verwenden Operator, um einen Befehl auszuführen, wenn der erste erfolgreich ist, zum Beispiel:
$ echo && echo "It works"
It works
$ nonexistantcommand && echo "This should not echo"
-bash: nonexistantcommand: command not found
Gut, also können wir tun..
ping -c 1 -t 1 192.168.1.1 &&echo "192.168.1.1 ist aktiv!"
Die andere Möglichkeit wäre, den Exit-Code von ping zu verwenden. Der Ping-Befehl wird mit dem Exit-Code 0 (Erfolg) beendet, wenn er funktioniert hat, und einem Nicht-Null-Code, wenn er fehlgeschlagen ist. In der Bash erhält man den Exit-Code des letzten Befehls mit der Variable $?
Um also zu überprüfen, ob der Befehl funktioniert hat, würden wir Folgendes tun..
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";
fi
Ausblenden der Ping-Ausgabe
Als letztes müssen wir die Ping-Ausgabe nicht sehen, also können wir stdout
umleiten bis /dev/null
mit dem >
Umleitung, zum Beispiel:
$ ping -c 1 -t 1 192.168.1.1 > /dev/null && echo "IP is up"
IP is up
Und um stderr
umzuleiten (um den ping: sendto: Host is down
zu verwerfen Nachrichten), verwenden Sie 2>
- zum Beispiel:
$ errorcausingcommand
-bash: errorcausingcommand: command not found
$ errorcausingcommand 2> /dev/null
$
Das Skript
Also, um all das zu kombinieren..
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
done
Oder verwenden Sie den &&
Methode in einem Einzeiler:
for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done
Problem
Es ist langsam.. Jeder Ping-Befehl dauert ungefähr 1 Sekunde (da wir das Flag -t timeout auf 1 Sekunde gesetzt haben). Es kann nur jeweils einen Ping-Befehl ausführen. Der offensichtliche Weg, dies zu umgehen, ist die Verwendung von Threads, sodass Sie gleichzeitige Befehle ausführen können, aber das geht über das hinaus, wofür Sie Bash verwenden sollten..
"Python-Threads - ein erstes Beispiel" erklärt, wie man das Python-Threading-Modul verwendet, um einen Multithread-Ping'er zu schreiben. Obwohl ich an dieser Stelle noch einmal vorschlagen würde, nmap -sn
zu verwenden ..
In der realen Welt könnten Sie nmap verwenden um zu bekommen, was Sie wollen.
nmap -sn 10.1.1.1-255
Dadurch werden alle Adressen im Bereich von 10.1.1.1 bis 10.1.1.255 angepingt und Sie erfahren, welche antworten.
Wenn Sie dies tatsächlich als Bash-Übung durchführen möchten, könnten Sie natürlich ping für jede Adresse ausführen und die Ausgabe parsen, aber das ist eine ganz andere Geschichte.
Angenommen, mein Netzwerk ist 10.10.0.0/24, wenn ich einen Ping auf die Broadcast-Adresse wie
ausführeping -b 10.10.0.255
Ich bekomme eine Antwort von allen Computern in diesem Netzwerk, die ihren ICMP-Ping-Port nicht blockiert haben.
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 ms
Sie müssen also nur die 4. Spalte extrahieren, zum Beispiel mit awk:
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:
Nun, Sie erhalten ein Duplikat und müssen möglicherweise das ':' entfernen.
BEARBEITEN von Kommentaren:Die Option -c begrenzt die Anzahl der Pings, da das Skript beendet wird, können wir uns auch auf eindeutige IPs beschränken
ping -c 5 -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }' | sort | uniq