Doporučil bych použít příznak ping-scan nmap,
$ 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
To znamená, že pokud to chcete napsat sami (což je fér), udělal bych to takto:
for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done
..a vysvětlení každého bitu výše uvedeného příkazu:
Generování seznamu IP adres
Můžete použít {1..10}
syntaxe pro vygenerování seznamu čísel, například...
$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
(je to také užitečné pro věci jako mkdir {dir1,dir2}/{sub1,sub2}
- což dělá dir1
a dir2
, z nichž každý obsahuje sub1
a sub2
)
Takže, abychom vygenerovali seznam IP, udělali bychom něco jako
$ echo 192.168.1.{1..10}
192.168.1.1 192.168.1.2 [...] 192.168.1.10
Smyčky
Chcete-li v bash něco přepnout do smyčky, použijte for
:
$ for thingy in 1 2 3; do echo $thingy; done
1
2
3
Ping
Dále k pingu.. Příkaz ping se trochu liší podle různých operačních systémů, různých distribucí/verzí (momentálně používám OS X)
Ve výchozím nastavení (opět na verzi OS X ping
) bude ping, dokud nebude přerušen, což v tomto případě nebude fungovat, takže ping -c 1
se pokusí odeslat pouze jeden paket, což by mělo stačit k určení, zda je počítač v provozu.
Dalším problémem je hodnota časového limitu, která se v této verzi pingu zdá být 11 sekund. Změní se pomocí -t
vlajka. Jedna sekunda by měla stačit k tomu, abyste viděli, zda je počítač v místní síti naživu nebo ne.
Takže příkaz ping, který použijeme, je...
$ 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
Kontrola výsledku pingu
Dále potřebujeme vědět, zda stroj odpověděl nebo ne..
Můžeme použít &&
operátor pro spuštění příkazu, pokud první uspěje, například:
$ echo && echo "It works"
It works
$ nonexistantcommand && echo "This should not echo"
-bash: nonexistantcommand: command not found
Dobře, takže můžeme..
ping -c 1 -t 1 192.168.1.1 &&echo "192.168.1.1 je aktivní!"
Druhým způsobem by bylo použití výstupního kódu z pingu. Příkaz ping skončí s výstupním kódem 0 (úspěch), pokud fungoval, a s nenulovým kódem, pokud selhal. V bash získáte výstupní kód posledních příkazů s proměnnou $?
Takže, abychom zkontrolovali, zda příkaz fungoval, udělali bychom...
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
Skrytí výstupu příkazu ping
Poslední věc, nepotřebujeme vidět výstup pingu, takže můžeme přesměrovat stdout
na /dev/null
s >
přesměrování, například:
$ ping -c 1 -t 1 192.168.1.1 > /dev/null && echo "IP is up"
IP is up
A k přesměrování stderr
(chcete-li zahodit ping: sendto: Host is down
zprávy), používáte 2>
- například:
$ errorcausingcommand
-bash: errorcausingcommand: command not found
$ errorcausingcommand 2> /dev/null
$
Skript
Takže, abychom to všechno spojili..
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
Nebo pomocí &&
metoda, v jedné vložce:
for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done
Problém
Je to pomalé. Každý příkaz ping trvá asi 1 sekundu (protože jsme nastavili příznak -t timeout na 1 sekundu). Může spustit pouze jeden příkaz ping najednou. Zřejmým způsobem, jak to obejít, je použití vláken, takže můžete spouštět souběžné příkazy, ale to je nad rámec toho, k čemu byste měli používat bash..
"Vlákna Pythonu – první příklad" vysvětluje, jak používat modul pro vytváření vláken v Pythonu k zápisu vícevláknového ping'eru. I když v tomto bodě bych ještě jednou doporučil použít nmap -sn
..
V reálném světě můžete použít nmap abyste dostali, co chcete.
nmap -sn 10.1.1.1-255
To odešle příkaz ping na všechny adresy v rozsahu 10.1.1.1 až 10.1.1.255 a dá vám vědět, které z nich odpověděly.
Samozřejmě, pokud to ve skutečnosti chcete udělat jako bash cvičení, můžete spustit ping pro každou adresu a analyzovat výstup, ale to je úplně jiný příběh.
Za předpokladu, že moje síť je 10.10.0.0/24, pokud spustím příkaz ping na adresu vysílání jako
ping -b 10.10.0.255
Dostanu odpověď od všech počítačů v této síti, které neblokovaly svůj 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 ms
Takže stačí extrahovat 4. sloupec, například pomocí 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:
No, dostanete duplikát a možná budete muset odstranit ':'.
UPRAVIT z komentářů:volba -c omezuje počet pingů, protože skript skončí, můžeme se také omezit na jedinečné IP adresy
ping -c 5 -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }' | sort | uniq