GNU/Linux >> Tutoriels Linux >  >> Linux

Comment puis-je écrire un script bash Linux qui m'indique quels ordinateurs sont allumés dans mon réseau local ?

Je suggérerais d'utiliser le drapeau ping-scan de 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

Cela dit, si vous voulez l'écrire vous-même (ce qui est assez juste), voici comment je procéderais :

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

..et une explication de chaque bit de la commande ci-dessus :

Génération d'une liste d'adresses IP

Vous pouvez utiliser le {1..10} syntaxe pour générer une liste de nombres, par exemple..

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

(c'est aussi utile pour des choses comme mkdir {dir1,dir2}/{sub1,sub2} - ce qui fait dir1 et dir2 , contenant chacun sub1 et sub2 )

Donc, pour générer une liste d'adresses IP, nous ferions quelque chose comme

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

Boucles

Pour boucler quelque chose dans bash, vous utilisez for :

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

Pinging

Ensuite, pour ping.. La commande ping varie un peu avec différents systèmes d'exploitation, différentes distributions/versions (j'utilise OS X actuellement)

Par défaut (encore une fois, sur la version OS X de ping ) il fera un ping jusqu'à ce qu'il soit interrompu, ce qui ne fonctionnera pas pour cela, donc ping -c 1 n'essaiera d'envoyer qu'un seul paquet, ce qui devrait être suffisant pour déterminer si une machine est en marche.

Un autre problème est la valeur du délai d'attente, qui semble être de 11 secondes sur cette version de ping. Elle est modifiée en utilisant le -t drapeau. Une seconde devrait suffire pour voir si une machine sur le réseau local est active ou non.

Donc, la commande ping que nous allons utiliser est...

$ 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

Vérification du résultat du ping

Ensuite, nous devons savoir si la machine a répondu ou non..

Nous pouvons utiliser le && opérateur pour exécuter une commande si la première réussit, par exemple :

$ echo && echo "It works"

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

Bon, donc on peut faire..

ping -c 1 -t 1 192.168.1.1 &&echo "192.168.1.1 est actif !"

L'autre façon serait d'utiliser le code de sortie de ping. La commande ping se terminera avec le code de sortie 0 (succès) si cela a fonctionné, et un code non nul si cela a échoué. En bash, vous obtenez le code de sortie des dernières commandes avec la variable $?

Donc, pour vérifier si la commande a fonctionné, nous ferions...

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

Masquer la sortie du ping

Dernière chose, nous n'avons pas besoin de voir la sortie du ping, nous pouvons donc rediriger stdout à /dev/null avec le > redirection, par exemple :

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

Et pour rediriger stderr (pour supprimer le ping: sendto: Host is down messages), vous utilisez 2> - par exemple :

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

Le scénario

Alors, pour combiner tout ça..

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

Ou, en utilisant le && méthode, dans un one-liner :

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

Problème

C'est lent. Chaque commande ping prend environ 1 seconde (puisque nous avons défini l'indicateur de délai d'attente -t ​​sur 1 seconde). Il ne peut exécuter qu'une seule commande ping à la fois. La solution évidente consiste à utiliser des threads, afin que vous puissiez exécuter des commandes simultanées, mais cela va au-delà de ce pour quoi vous devriez utiliser bash..

"Threads Python - un premier exemple" explique comment utiliser le module de threading Python pour écrire un ping'er multi-thread. Bien qu'à ce stade, je suggérerais à nouveau d'utiliser nmap -sn ..


Dans le monde réel, vous pourriez utiliser nmap pour obtenir ce que vous voulez.

nmap -sn 10.1.1.1-255

Cela enverra un ping à toutes les adresses de la plage 10.1.1.1 à 10.1.1.255 et vous indiquera celles qui répondent.

Bien sûr, si vous voulez en fait faire cela comme un exercice bash, vous pouvez exécuter ping pour chaque adresse et analyser la sortie, mais c'est une toute autre histoire.


En supposant que mon réseau est 10.10.0.0/24, si je lance un ping sur l'adresse de diffusion comme

ping -b 10.10.0.255

J'obtiendrai une réponse de tous les ordinateurs de ce réseau qui n'ont pas bloqué leur port 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 

Il vous suffit donc d'extraire la 4ème colonne, avec awk par exemple :

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:

Eh bien, vous obtiendrez un doublon et vous devrez peut-être supprimer le ':'.

EDIT depuis les commentaires :l'option -c limite le nombre de pings puisque le script va se terminer, on peut aussi se limiter aux IP uniques

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

Linux
  1. Comment puis-je exécuter un script Perl en tant que démon système sous Linux ?

  2. Comment puis-je vérifier si PostgreSQL est installé ou non via un script Linux ?

  3. Comment puis-je savoir sous Linux quel processus a envoyé un signal à mon processus

  4. Comment puis-je tester mon script Bash sur des versions plus anciennes de Bash ?

  5. Comment puis-je répondre automatiquement aux invites d'un script Linux Bash ?

Comment écrire un script bash avec des exemples

Shell Scripting pour les débutants - Comment écrire des scripts Bash sous Linux

Comment trouver la version de Linux que vous utilisez

Comment puis-je vérifier quels ports sont occupés et quels ports sont libres sur ma machine Linux ?

Comment puis-je activer Ping sur une machine virtuelle Azure Linux

Comment puis-je vérifier si les cgroups sont disponibles sur mon hôte Linux ?