web-dev-qa-db-fra.com

Script de ping multiple en Python

Je suis incapable de trouver une bonne documentation facile à apprendre sur Python et les réseaux. Dans ce cas, j'essaie simplement de créer un script simple permettant de faire un ping sur un certain nombre de machines distantes.

for ping in range(1,10):
   ip="127.0.0."+str(ping)
   os.system("ping -c 3 %s" % ip)

Un script simple comme celui-ci envoie une requête ping aux machines, mais j'aimerais que le script retourne le mot 'actif' 'pas de réponse'. Ce qui me fait penser que je devrai également regarder le module de temps, je pense que time.sleep(5) and après cela, il y aurait une déclaration de rupture. Ce qui me fait penser qu'il devrait y avoir une boucle while à l'intérieur pour. Je ne suis pas sûr à 100%, je pourrais aller complètement dans la mauvaise direction:/si quelqu'un pouvait m'aider ou m'indiquer des documents, ce serait formidable.

18
kuiper

Essayez subprocess.call. Il enregistre la valeur de retour du programme utilisé.

Selon mon manuel de ping, il renvoie 0 en cas de succès, 2 lorsque les pings ont été envoyés, mais qu'aucune réponse n'a été reçue et toute autre valeur indique une erreur.

# typo error in import
import subprocess

for ping in range(1,10):
    address = "127.0.0." + str(ping)
    res = subprocess.call(['ping', '-c', '3', address])
    if res == 0:
        print "ping to", address, "OK"
    Elif res == 2:
        print "no response from", address
    else:
        print "ping to", address, "failed!"
25
Roland Smith

Ce script:

import subprocess
import os
with open(os.devnull, "wb") as limbo:
        for n in xrange(1, 10):
                ip="192.168.0.{0}".format(n)
                result=subprocess.Popen(["ping", "-c", "1", "-n", "-W", "2", ip],
                        stdout=limbo, stderr=limbo).wait()
                if result:
                        print ip, "inactive"
                else:
                        print ip, "active"

produira quelque chose comme cette sortie:

192.168.0.1 active
192.168.0.2 active
192.168.0.3 inactive
192.168.0.4 inactive
192.168.0.5 inactive
192.168.0.6 inactive
192.168.0.7 active
192.168.0.8 inactive
192.168.0.9 inactive

Vous pouvez capturer la sortie si vous remplacez limbo par subprocess.PIPE et utilisez communicate() sur l'objet Popen:

p=Popen( ... )
output=p.communicate()
result=p.wait()

De cette façon, vous obtenez la valeur de retour de la commande et pouvez capturer le texte. Suivant le manual , c’est le moyen privilégié d’exploiter un sous-processus si vous avez besoin de souplesse:

La création et la gestion du processus sous-jacent dans ce module est géré par la classe Popen. Il offre beaucoup de flexibilité pour que Les développeurs sont en mesure de traiter les cas moins courants non couverts par le fonctions de commodité.

9
hochl

Merci beaucoup pour cela. Je l'ai modifié pour fonctionner avec Windows. J'ai également mis un délai d'expiration peu élevé afin que les adresses IP qui n'ont pas de retour ne restent pas en attente et attendent 5 secondes chacune. Ceci provient du code source de hochl.

import subprocess
import os
with open(os.devnull, "wb") as limbo:
        for n in xrange(200, 240):
                ip="10.2.7.{0}".format(n)
                result=subprocess.Popen(["ping", "-n", "1", "-w", "200", ip],
                        stdout=limbo, stderr=limbo).wait()
                if result:
                        print ip, "inactive"
                else:
                        print ip, "active"

Il suffit de changer l'ip = pour votre schéma et le xrange pour les hôtes.

5
Robert N

Je suis un débutant et ai écrit un script pour envoyer une requête ping à plusieurs hôtes. Pour envoyer une requête ping à plusieurs hôtes, vous pouvez utiliser le module ipaddress. 

import ipaddress
from subprocess import Popen, PIPE

net4 = ipaddress.ip_network('192.168.2.0/24')
for x in net4.hosts():
    x = str(x)
    hostup = Popen(["ping", "-c1", x], stdout=PIPE)
    output = hostup.communicate()[0]
    val1 = hostup.returncode
 if val1 == 0:
    print(x, "is pinging")
 else:
    print(x, "is not responding")
3
Sumit

Pour envoyer un ping à plusieurs hôtes à la fois, vous pouvez utiliser subprocess.Popen():

#!/usr/bin/env python3
import os
import time
from subprocess import Popen, DEVNULL

p = {} # ip -> process
for n in range(1, 100): # start ping processes
    ip = "127.0.0.%d" % n
    p[ip] = Popen(['ping', '-n', '-w5', '-c3', ip], stdout=DEVNULL)
    #NOTE: you could set stderr=subprocess.STDOUT to ignore stderr also

while p:
    for ip, proc in p.items():
        if proc.poll() is not None: # ping finished
            del p[ip] # remove from the process list
            if proc.returncode == 0:
                print('%s active' % ip)
            Elif proc.returncode == 1:
                print('%s no response' % ip)
            else:
                print('%s error' % ip)
            break

Si vous pouvez vous lancer en tant que root, vous pouvez utiliser un script ping Python pure ou scapy :

from scapy.all import sr, ICMP, IP, L3RawSocket, conf

conf.L3socket = L3RawSocket # for loopback interface
ans, unans = sr(IP(dst="127.0.0.1-99")/ICMP(), verbose=0) # make requests
ans.summary(lambda (s,r): r.sprintf("%IP.src% is alive"))
2
jfs
import subprocess
import os
'''
servers.txt contains ip address in following format
192.168.1.1
192.168.1.2
'''
    with open('servers.txt', 'r') as f:
        for ip in f:
            result=subprocess.Popen(["ping", "-c", "1", "-n", "-W", "2",    ip],stdout=f, stderr=f).wait()
            if result:
                print(ip, "inactive")
            else:
                print(ip, "active")
1
Razi Ahmed

Python a en fait une méthode vraiment adorable qui "retournera un itérateur sur les hôtes utilisables du réseau". (définir strict sur false itère sur toutes les adresses IP)

Par exemple:

import subprocess
import ipaddress

subnet = ipaddress.ip_network('192.168.1.0/24', strict=False)
for i in subnet.hosts():
    i = str(i)
    subprocess.call(["ping", "-c1", "-n", "-i0.1", "-W1", i])

L’intervalle d’attente (-i0.1) peut être important pour les automatisations. Même un délai d’attente d’une seconde (-t1) peut durer indéfiniment au-delà de 0,01.

EDIT: Ainsi, afin de suivre les demandes ICMP (ping), nous pouvons faire quelque chose comme ceci:

#!/usr/bin/env python

import subprocess
import ipaddress

alive = []
subnet = ipaddress.ip_network('192.168.1.0/23', strict=False)
for i in subnet.hosts():
    i = str(i)
    retval = subprocess.call(["ping", "-c1", "-n", "-i0.1", "-W1", i])
    if retval == 0:
        alive.append(i)
for ip in alive:
    print(ip + " is alive") 

Ce qui retournera quelque chose comme:

192.168.0.1 is alive
192.168.0.2 is alive
192.168.1.1 is alive
192.168.1.246 is alive

c'est-à-dire que toutes les adresses IP répondant à ICMP s'étalant sur un entier/23-- plutôt cool!

0
andylukem