it-swarm.com.de

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

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

Es würde helfen, wenn ich ihm als Eingabe einen Bereich von IPs geben könnte.

32
Dumb Questioner

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 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 jedes Bits des obigen Befehls:

Liste der IP-Adressen erstellen

Sie können die {1..10}-Syntax verwenden, um beispielsweise eine Liste mit Zahlen zu generieren.

$ 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 und dir2 macht, wobei jedes sub1 und sub2 enthält)

Um eine Liste von IPs zu erstellen, würden wir so etwas tun

$ echo 192.168.1.{1..10}
192.168.1.1 192.168.1.2 [...] 192.168.1.10

Schleifen

Um in bash etwas zu durchlaufen, verwenden Sie for:

$ for thingy in 1 2 3; do echo $thingy; done
1
2
3

Pinging

Weiter zum Ping .. Der Ping-Befehl variiert ein wenig mit verschiedenen Betriebssystemen, verschiedenen Distributionen/Versionen (Ich verwende derzeit OS X).

Standardmäßig (wieder auf der OS X-Version von ping) wird bis zu einer Unterbrechung ein Ping durchgeführt. Dies wird jedoch nicht funktionieren. Daher wird ping -c 1 nur versuchen, ein Paket zu senden. Dies sollte ausreichen, um festzustellen, ob eine Maschine in Betrieb ist.

Ein anderes Problem ist der Timeout-Wert, der bei dieser Ping-Version scheinbar 11 Sekunden beträgt. Er wurde mit dem Flag -t geändert. Eine Sekunde sollte ausreichen, um zu sehen, ob eine Maschine im lokalen Netzwerk aktiv ist oder nicht.

Also ist der Ping-Befehl, den wir verwenden werden ..

$ 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

Überprüfen des Ping-Ergebnisses

Als Nächstes müssen wir wissen, ob der Computer geantwortet hat oder nicht ..

Wir können den Operator && verwenden, um einen Befehl auszuführen, wenn der erste Befehl erfolgreich ist. Beispiel:

$ echo && echo "It works"

It works
$ nonexistantcommand && echo "This should not echo"
-bash: nonexistantcommand: command not found

Gut, also können wir das machen ..

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 Exit-Code 0 (Erfolg) beendet, wenn er funktioniert hat, und einem Nicht-Null-Code, falls er fehlgeschlagen ist. In Bash erhalten Sie den letzten Kommando-Exit-Code mit der Variablen $?.

Um zu überprüfen, ob der Befehl funktioniert hat, tun wir das ..

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

Ping-Ausgabe ausblenden

Als letztes müssen wir die Ping-Ausgabe nicht sehen, sodass wir stdout mit der /dev/null-Umleitung zu > umleiten können, zum Beispiel:

$ ping -c 1 -t 1 192.168.1.1 > /dev/null && echo "IP is up"
IP is up

Um stderr umzuleiten (um die ping: sendto: Host is down-Nachrichten zu verwerfen), verwenden Sie 2> - zum Beispiel:

$ errorcausingcommand
-bash: errorcausingcommand: command not found
$ errorcausingcommand 2> /dev/null
$

Das Skript

Also, 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 die 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 etwa 1 Sekunde (da wir das Zeitlimit für -t auf 1 Sekunde setzen). Es kann jeweils nur ein Ping-Befehl ausgeführt werden. Die naheliegendste Möglichkeit besteht darin, Threads zu verwenden, sodass Sie gleichzeitige Befehle ausführen können, aber dafür sollten Sie nicht bash verwenden.

"Python-Threads - ein erstes Beispiel" erläutert die Verwendung des Python-Threading-Moduls zum Schreiben eines Multithread-Ping'er. Obwohl ich an dieser Stelle noch einmal nmap -sn ..

77
dbr

In der realen Welt können Sie nmap verwenden, um das zu bekommen, was Sie möchten.

nmap -sn 10.1.1.1-255

Dadurch werden alle Adressen im Bereich 10.1.1.1 bis 10.1.1.255 per Ping angesprochen und Sie wissen, welche Antworten antworten. 

Wenn Sie dies tatsächlich als Bash-Übung durchführen möchten, können Sie natürlich für jede Adresse einen Ping-Befehl ausführen und die Ausgabe analysieren.

14
Tiberiu Ana

Angenommen, mein Netzwerk ist 10.10.0.0/24, wenn ich einen Ping auf die Broadcast-Adresse ausführen möchte

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 bekommen ein Duplikat und müssen 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
10
chburd

Es gibt auch fping :

fping -g 192.168.1.0/24

oder:

fping -g 192.168.1.0 192.168.1.255

oder nur lebende Hosts anzeigen:

fping -ag 192.168.1.0/24

Es pingt Hosts parallel, so dass der Scan sehr schnell ist. Ich kenne keine Distribution, die fping in ihrer Standardinstallation enthält, aber in den meisten Distributionen können Sie sie über den Paketmanager erhalten.

8
d0k

Mit der von chburd angegebenen "Ping-Broadcast-Adresse" -Methode sollte diese Pipe den Trick für Sie tun:

ping -c 5 -b 10.11.255.255 | sed -n 's/.* \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p' | sort | uniq

Natürlich müssen Sie die Broadcast-Adresse in die Adresse Ihres Netzwerks ändern.

2
Can Berk Güder

Nur zum Spaß, hier ist eine Alternative


     #!/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,\),,
2
Eddy

Wenn Sie sich darauf beschränken, nur das letzte Oktett zu ändern, sollte dieses Skript dies tun. Es sollte ziemlich offensichtlich sein, wie es von einem auf mehrere Oktette erweitert werden kann.

 #! /bin/bash
BASE=$1
START=$2
END=$3

counter=$START

, während [$ counterlele $ END] 
 tun
 ip = $ BASE. $ counter 
 wenn ping -qc 2 $ ip 
 dann
 echo "$ ip antwortet" 
 fi 
 counter = $ (($ counter + 1)) 
 erledigt 
1
Vatine

Wie auf anderen Plakaten gezeigt wurde, ist nmap der Weg, aber wie folgt das Äquivalent eines Ping-Scans in bash. Ich würde den Broadcast-Ping nicht verwenden, da viele Systeme so konfiguriert sind, dass sie heutzutage nicht mehr auf Broadcast-ICMP reagieren.

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
1
Don Werve

Einige Maschinen beantworten keine Pings (z. B. Firewalls).

Wenn Sie nur das lokale Netzwerk möchten, können Sie diesen Befehl verwenden:

(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]+'

Erläuterungen Teil!

  1. arping ist ein Befehl, der ARP-Anforderungen sendet. Es ist auf den meisten Linux vorhanden. 

Beispiel:

Sudo arping -c1 10.0.0.14

der Sudo ist nicht notwendig, wenn Sie root ofc sind.

  • 10.0.0.14: die IP, die Sie testen möchten
  • -c1: Nur eine Anfrage senden.

  1. &: das Zeichen "Ich möchte nicht warten"

Dies ist ein wirklich nützlicher Charakter, der Ihnen die Möglichkeit gibt, einen Befehl in einem Unterprozess zu starten, ohne ihn zu warten (wie ein Thread)


  1. die for Schleife ist hier, um alle 255 IP-Adressen zu erstellen. Es verwendet den Befehl seq, um alle Zahlen aufzulisten.

  1. wait: Nachdem wir unsere Anfragen gestellt haben, möchten wir sehen, ob es Antworten gibt. Dazu setzen wir einfach wait nach der Schleife .wait Sieht aus wie die Funktion join() in anderen Sprachen.

  1. (): Klammern sind hier, um alle Ausgaben als Text zu interpretieren, damit wir ihn an grep übergeben können.

  1. grep: wir möchten nur Antworten sehen. Der zweite grep dient nur dazu, IPs hervorzuheben.

hth

Edit 20150417: Maxi-Update!

Das Schlimme an meiner Lösung ist, dass am Ende alle Ergebnisse gedruckt werden. Da grep über einen ausreichend großen Puffer verfügt, um einige Zeilen hineinzugeben. Die Lösung besteht darin, --line-buffered zum ersten grep . Hinzuzufügen:

(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]+'
1
Boop

Obwohl es eine alte Frage ist, scheint es immer noch wichtig zu sein (zumindest so wichtig, dass ich damit umgehen kann). Mein Skript basiert auch auf nmap, also nichts Besonderes, außer dass Sie definieren können, welche Schnittstelle Sie scannen möchten, und der IP-Bereich automatisch (zumindest irgendwie) erstellt wird.

Das ist was ich mir ausgedacht habe

#!/bin/bash
#Script for scanning the (local) network for other computers 

command -v nmap >/dev/null 2>&1 || { echo "I require nmap but it's not installed. Aborting." >&2; exit 1; }

if [ -n ""[email protected]"" ];  then
    ip=$(/sbin/ifconfig $1 | grep 'inet '  | awk '{ print $2}' | cut -d"." -f1,2,3 )
    nmap -sP $ip.1-255
else
    echo -e "\nThis is a script for scanning the (local) network for other computers.\n"
    echo "Enter Interface as parameter like this:"
    echo -e "\t./scannetwork.sh $(ifconfig -lu | awk '{print $2}')\n"

    echo "Possible interfaces which are up are: "   
    for i in $(ifconfig -lu)
    do
        echo -e "\033[32m \t $i \033[39;49m"
    done

    echo "Interfaces which could be used but are down at the moment: "
    for i in $(ifconfig -ld)
    do
        echo -e "\033[31m \t $i \033[39;49m"
    done
    echo
fi

Eine Anmerkung: Dieses Skript wurde unter OSX erstellt. Daher können Änderungen an Linux-Umgebungen vorgenommen werden.

1
d3v3l
#!/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
1
hemanth.hm

Wenn Sie eine Liste von Hosts bereitstellen möchten, können Sie dies mit nmap, grep und awk tun.

Nmap installieren:

$ Sudo apt-get install nmap

Erstellen Sie die Datei hostcheck.sh wie folgt:

hostcheck.sh

#!/bin/bash

nmap -sP -iL hostlist -oG pingscan > /dev/null
grep Up pingscan | awk '{print $2}' > uplist
grep Down pingscan | awk '{print $2}' > downlist

-sP: Ping-Scan - Bestimmen Sie nicht, ob der Host online ist

-iL: Eingabe aus der Liste der Hosts/Netzwerke

-oG: Ausgabe der Scan-Ergebnisse im Grepable-Format unter dem angegebenen Dateinamen.

/ dev/null: Verwirft die Ausgabe

Ändern Sie die Zugriffsberechtigung:

$ chmod 775 hostcheck.sh

Erstellen Sie eine Dateihostliste mit der Liste der zu überprüfenden Hosts (Hostname oder IP):

hostliste (Beispiel)

192.168.1.1-5
192.168.1.101
192.168.1.123

192.168.1.1-5 ist eine Reihe von IPs

Führen Sie das Skript aus:

./hostcheck.sh hostfile

Es werden Dateien generiert, die alle Informationen pingscan, Uplist bei den Hosts online (Up) und Downlist bei den Hosts offline (Down).

uplist (Beispiel)

192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.101

downlist (Beispiel)

192.168.1.5
192.168.1.123
1
viniciusfcosta
1
raspi

Der folgende (böse) Code läuft mehr als ZWEIMAL so schnell wie die nmap-Methode

for i in {1..254} ;do (ping 192.168.1.$i -c 1 -w 5  >/dev/null && echo "192.168.1.$i" &) ;done

dauert etwa 10 Sekunden, wobei die Standardnap

nmap -sP 192.168.1.1-254

dauert 25 Sekunden ...

0
Mike Redrobe

Nun, das ist Teil eines Skripts von mir.

ship.sh ???? Eine einfache, praktische Netzwerkadressierung ???? Multitool mit vielen Funktionen ????

Pings-Netzwerk, zeigt Online-Hosts in diesem Netzwerk mit ihrer lokalen IP- und MAC-Adresse an

Es ist keine Bearbeitung erforderlich. Benötigt Root-Berechtigung zum Ausführen.

GOOGLE_DNS="8.8.8.8"
ONLINE_INTERFACE=$(ip route get "${GOOGLE_DNS}" | awk -F 'dev ' 'NR == 1 {split($2, a, " "); print a[1]}')
NETWORK_IP=$(ip route | awk "/${ONLINE_INTERFACE}/ && /src/ {print \$1}" | cut --fields=1 --delimiter="/")
NETWORK_IP_CIDR=$(ip route | awk "/${ONLINE_INTERFACE}/ && /src/ {print \$1}")
FILTERED_IP=$(echo "${NETWORK_IP}" | awk 'BEGIN{FS=OFS="."} NF--')

ip -statistics neighbour flush all &>/dev/null

echo -ne "Pinging ${NETWORK_IP_CIDR}, please wait ..."
for Host in {1..254}; do
  ping "${FILTERED_IP}.${Host}" -c 1 -w 10 &>/dev/null &
done

for JOB in $(jobs -p); do wait "${JOB}"; done

ip neighbour | \
    awk 'tolower($0) ~ /reachable|stale|delay|probe/{printf ("%5s\t%s\n", $1, $5)}' | \
      sort --version-sort --unique
0
xtonousou
#!/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
0
erik