Множественный пинг script в Python
Я не могу найти какую-либо хорошую легкую для изучения документацию на python и в сети. В этом случае я просто пытаюсь сделать легкий script, который я могу выполнить ping на нескольких удаленных машинах.
for ping in range(1,10):
ip="127.0.0."+str(ping)
os.system("ping -c 3 %s" % ip)
Простой script, как это будет ping машины отлично, но я хотел бы получить script для возврата 'active' 'no response' Что заставляет меня думать, что мне придется искать модуль времени также, я думаю, time.sleep(5)
, и после этого будет выражение о разрыве. Это заставляет меня думать, что внутри должен быть цикл while. Я не уверен на 100%, я мог бы пойти в неправильном направлении полностью:/если кто-то может помочь или указать мне в сторону какой-то документации, которая будет великолепной.
Ответы
Ответ 1
Попробуйте subprocess.call
. Он сохраняет возвращаемое значение используемой программы.
Согласно моему руководству ping, он возвращает 0 при успехе, 2 при отправке писем, но ответ не получен, а любое другое значение указывает на ошибку.
# 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!"
Ответ 2
Этот 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"
будет выдавать что-то вроде этого вывода:
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
Вы можете записать вывод, если вы замените limbo
на subprocess.PIPE
и используйте communicate()
в объекте Popen
:
p=Popen( ... )
output=p.communicate()
result=p.wait()
Таким образом вы получаете возвращаемое значение команды и можете захватывать текст. Следуя manual, это предпочтительный способ работы с подпроцессом, если вам нужна гибкость:
Создание и управление базовым процессом в этом модуле обработанный классом Popen. Он предлагает большую гибкость, так что разработчики могут обрабатывать менее распространенные случаи, не охватываемые удобные функции.
Ответ 3
Большое вам спасибо за это. Я изменил его для работы с Windows. Я также поставил низкий тайм-аут, поэтому IP, у которого нет возврата, не будет сидеть и ждать 5 секунд каждый. Это из исходного кода 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"
Просто измените ip = для вашей схемы и xrange для хостов.
Ответ 4
Я новичок и написал script для ping нескольких хостов. Чтобы выполнить ping на нескольких хостах, вы можете использовать модуль 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")
Ответ 5
Чтобы выполнить ping сразу несколько хостов, вы можете использовать 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
Если вы можете запускать в качестве корня, вы можете использовать чистый Pingon ping script или 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"))
Ответ 6
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")
Ответ 7
У Python действительно есть действительно сладкий метод который будет "возвращать итератор поверх используемых компьютеров в сети" . (установка строго для ложных итераций по всем IP-адресам)
Например:
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])
Интервал ожидания (-i0.1) может быть важен для автоматизации, даже один секунда тайм-аута (-t1) может длиться вечно над .0/24
ИЗМЕНИТЬ:
Итак, чтобы отслеживать запросы ICMP (ping), мы можем сделать что-то вроде этого:
#!/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")
Что вернет что-то вроде:
192.168.0.1 is alive
192.168.0.2 is alive
192.168.1.1 is alive
192.168.1.246 is alive
то есть. все IP-адреса, реагирующие на ICMP, охватывают весь /23-- Довольно круто!
Ответ 8
Проверьте это: https://github.com/thiagocavalcanti/pingMonitor
Этот скрипт поможет вам!
Ответ 9
import subprocess,os,threading,time
from queue import Queue
lock=threading.Lock()
_start=time.time()
def check(n):
with open(os.devnull, "wb") as limbo:
ip="192.168.21.{0}".format(n)
result=subprocess.Popen(["ping", "-n", "1", "-w", "300", ip],stdout=limbo, stderr=limbo).wait()
with lock:
if not result:
print (ip, "active")
else:
pass
def threader():
while True:
worker=q.get()
check(worker)
q.task_done()
q=Queue()
for x in range(255):
t=threading.Thread(target=threader)
t.daemon=True
t.start()
for worker in range(1,255):
q.put(worker)
q.join()
print("Process completed in: ",time.time()-_start)
Я думаю, что это будет лучше.