GNU/Linux >> Linux Esercitazione >  >> Linux

Come posso scrivere uno script bash di Linux che mi dica quali computer sono ACCESI nella mia LAN?

Suggerirei di usare il flag ping-scan di 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

Detto questo, se vuoi scriverlo tu stesso (il che è abbastanza giusto), ecco come lo farei:

for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done

..e una spiegazione di ogni bit del comando precedente:

Generazione elenco di indirizzi IP

Puoi usare il {1..10} sintassi per generare un elenco di numeri, ad esempio...

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10

(è anche utile per cose come mkdir {dir1,dir2}/{sub1,sub2} - che fa dir1 e dir2 , ciascuno contenente sub1 e sub2 )

Quindi, per generare un elenco di IP, faremmo qualcosa del genere

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

Loop

Per eseguire il loop su qualcosa in bash, si usa for :

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

Ping

Successivamente, ping.. Il comando ping varia leggermente con diversi sistemi operativi, diverse distribuzioni/versioni (attualmente sto usando OS X)

Per impostazione predefinita (di nuovo, nella versione OS X di ping ) eseguirà il ping fino a quando non verrà interrotto, il che non funzionerà per questo, quindi ping -c 1 tenterà di inviare solo un pacchetto, che dovrebbe essere sufficiente per determinare se una macchina è attiva.

Un altro problema è il valore di timeout, che sembra essere di 11 secondi su questa versione di ping.. È cambiato usando -t bandiera. Un secondo dovrebbe essere sufficiente per vedere se una macchina sulla rete locale è attiva o meno.

Quindi, il comando ping che useremo è..

$ 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

Controllo del risultato del ping

Successivamente, dobbiamo sapere se la macchina ha risposto o meno..

Possiamo usare il && operatore per eseguire un comando se il primo ha esito positivo, ad esempio:

$ echo && echo "It works"

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

Bene, quindi possiamo fare...

ping -c 1 -t 1 192.168.1.1 &&echo "192.168.1.1 è attivo!"

L'altro modo sarebbe utilizzare il codice di uscita da ping.. Il comando ping terminerà con il codice di uscita 0 (successo) se ha funzionato e un codice diverso da zero se ha avuto esito negativo. In bash ottieni il codice di uscita degli ultimi comandi con la variabile $?

Quindi, per verificare se il comando ha funzionato, faremmo...

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

Nascondere l'output del ping

Ultima cosa, non abbiamo bisogno di vedere l'output del ping, quindi possiamo reindirizzare stdout a /dev/null con il > reindirizzamento, ad esempio:

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

E per reindirizzare stderr (per eliminare il ping: sendto: Host is down messaggi), usi 2> - ad esempio:

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

Il copione

Quindi, per combinare tutto questo...

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

Oppure, usando il && metodo, in una riga:

for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done

Problema

È lento... Ogni comando ping richiede circa 1 secondo (poiché abbiamo impostato il flag -t timeout su 1 secondo). Può eseguire solo un comando ping alla volta.. Il modo ovvio per aggirare questo è usare i thread, in modo da poter eseguire comandi simultanei, ma questo va oltre ciò per cui dovresti usare bash..

"Python threads - a first example" spiega come usare il modulo Python threading per scrivere un ping'er multi-thread. Anche se a quel punto, suggerirei ancora una volta di usare nmap -sn ..


Nel mondo reale, potresti usare nmap per ottenere quello che vuoi.

nmap -sn 10.1.1.1-255

Questo eseguirà il ping di tutti gli indirizzi nell'intervallo da 10.1.1.1 a 10.1.1.255 e ti farà sapere quali rispondono.

Ovviamente, se in realtà vuoi farlo come esercizio di bash, puoi eseguire il ping per ogni indirizzo e analizzare l'output, ma questa è tutta un'altra storia.


Supponendo che la mia rete sia 10.10.0.0/24, se eseguo un ping sull'indirizzo di trasmissione come

ping -b 10.10.0.255

Riceverò una risposta da tutti i computer su questa rete che non hanno bloccato la loro porta ping ICMP.

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 

Quindi devi solo estrarre la quarta colonna, con awk per esempio:

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:

Bene, otterrai un duplicato e potresti dover rimuovere ':'.

EDIT dai commenti:l'opzione -c limita il numero di ping poiché lo script terminerà, possiamo anche limitarci su IP univoci

ping -c 5 -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }' | sort | uniq

Linux
  1. Come utilizzare la password crittografata nello script della shell Bash Linux

  2. Come sapere quale distribuzione Linux stai utilizzando?

  3. Come eseguire un comando bash Linux in uno script PERL?

  4. Come trovare quale shell stai usando su Linux

  5. Come posso verificare se PostgreSQL è installato o meno tramite script Linux?

Come scrivere uno script Bash con esempi

Script di shell per principianti - Come scrivere script Bash in Linux

Come aggiungere un utente Unix/linux in uno script Bash?

Come trovare la versione di Linux in esecuzione

Come posso verificare quali porte sono occupate e quali porte sono libere sulla mia macchina Linux?

Come posso risolvere un nome host in un indirizzo IP in uno script Bash?