GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie kann ich ein Linux-Bash-Skript schreiben, das mir mitteilt, welche Computer in meinem LAN eingeschaltet sind?

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ühre
ping -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

Linux
  1. Wie überprüfe ich den Internetzugang mit Bash-Skript in Linux?

  2. Wie kann ich mein Bash-Skript auf älteren Bash-Versionen testen?

  3. Wie kann ich automatisch auf Eingabeaufforderungen in einem Linux-Bash-Skript reagieren?

  4. Wie kann ich Ping auf einer Azure-Linux-VM aktivieren

  5. Wie kann ich überprüfen, ob cgroups auf meinem Linux-Host verfügbar sind?

So schreiben Sie ein Bash-Skript mit Beispielen

Shell-Scripting für Anfänger – So schreiben Sie Bash-Scripts unter Linux

So finden Sie heraus, welche Linux-Version Sie ausführen

Wie kann ich überprüfen, welche Ports belegt und welche Ports auf meinem Linux-Rechner frei sind?

Wie kann ich in einem Bash-Skript einen Hostnamen in eine IP-Adresse auflösen?

Wie kann ich feststellen, welcher Prozess UDP-Verkehr unter Linux verursacht?