GNU/Linux >> Znalost Linux >  >> Linux

Jak mohu napsat linuxový bash skript, který mi řekne, které počítače jsou v mé LAN zapnuté?

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

Linux
  1. Jak přidat uživatele Unix/linux do skriptu Bash?

  2. Jak mohu spustit skript v Perlu jako systémový démon v linuxu?

  3. Jak mohu zkontrolovat, zda je PostgreSQL nainstalován nebo ne prostřednictvím skriptu Linux?

  1. Jak mohu v Linuxu zjistit, který proces poslal mému procesu signál

  2. Jak zkontrolovat přístup k internetu pomocí bash skriptu v linuxu?

  3. Jak mohu zkontrolovat, které porty jsou na mém počítači se systémem Linux obsazené a které volné?

  1. Jak mohu otestovat svůj Bash skript na starších verzích Bash?

  2. Jak mohu přeložit název hostitele na IP adresu ve skriptu Bash?

  3. Jak mohu zjistit, který proces vytváří UDP provoz v Linuxu?