Ответы:
Эта функция работает в любой ОС (Unix, Linux, macOS и Windows)
Python 2 и Python 3
Правок:
По @radato os.system
был заменен subprocess.call
. Это позволяет избежать уязвимости внедрения оболочки в тех случаях, когда строка имени вашего хоста может не проверяться.
import platform # For getting the operating system name
import subprocess # For executing a shell command
def ping(host):
"""
Returns True if host (str) responds to a ping request.
Remember that a host may not respond to a ping (ICMP) request even if the host name is valid.
"""
# Option for the number of packets as a function of
param = '-n' if platform.system().lower()=='windows' else '-c'
# Building the command. Ex: "ping -c 1 google.com"
command = ['ping', param, '1', host]
return subprocess.call(command) == 0
Обратите внимание, что, согласно @ikrase в Windows, эта функция все равно будет возвращаться, True
если вы получите Destination Host Unreachable
ошибку.
объяснение
Команда применяется ping
как в Windows, так и в Unix-подобных системах.
Опция -n
(Windows) или -c
(Unix) контролирует количество пакетов, которое в этом примере было установлено на 1.
platform.system()
возвращает имя платформы Ex. 'Darwin'
на macOS.
subprocess.call()
выполняет системный вызов. Ex. subprocess.call(['ls','-l'])
,
ping 8.8.8.8 -n 1
3) echo %ERRORLEVEL%
. Код: измените последнюю строку кода Python на return system_call(command)
. При правильном подключении вы получите 0 (ноль). При выключенном модеме вы должны получить код ошибки. Конечно, оба метода должны возвращать один и тот же код ошибки при одинаковых условиях.
Если вам не нужна поддержка Windows, вот очень краткий способ сделать это:
import os
hostname = "google.com" #example
response = os.system("ping -c 1 " + hostname)
#and then check the response...
if response == 0:
print hostname, 'is up!'
else:
print hostname, 'is down!'
Это работает, потому что ping возвращает ненулевое значение в случае сбоя соединения. (Возвращаемое значение на самом деле отличается в зависимости от ошибки сети.) Вы также можете изменить время ожидания пинга (в секундах), используя опцию -t. Обратите внимание, это выведет текст на консоль.
response = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
man ping
чтобы убедиться.
hostname
строку от пользователя, он может легко взломать ваш сервер, дав вам URL-адрес 'google.com; rm -rf /*'
. Используйте subprocess.run(["ping", "-c", "1", hostname]).returncode
вместо этого.
Существует модуль, называемый pyping, который может сделать это. Может быть установлен с пипс
pip install pyping
Использовать его довольно просто, однако при использовании этого модуля вам нужен root-доступ, поскольку он создает необработанные пакеты под капотом.
import pyping
r = pyping.ping('google.com')
if r.ret_code == 0:
print("Success")
else:
print("Failed with {}".format(r.ret_code))
os.system('ping -c 1 -t 1 hostname')
решение. Кроме того, pyping
библиотека очень проста в использовании по сравнению с библиотекой сокетов TCP / IP. Я написал свою программу ping, используя и то, и другое, и pyping
, на мой взгляд, гораздо быстрее и проще в использовании, особенно если кто-то не знаком с использованием библиотеки сокетов TCP / IP.
pip install ping3
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()
whereis ping
чтобы получить правильный путь.
ping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
Для python3 есть очень простой и удобный модуль python ping3 : ( pip install ping3
, требуются права суперпользователя ).
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>> 0.215697261510079666
Этот модуль также позволяет настраивать некоторые параметры.
Поскольку мне нравится, что моя программа Python универсальна для версий 2.7 и 3.x, а также для платформ Linux, Mac OS и Windows, мне пришлось изменить существующие примеры.
# shebang does not work over all platforms
# ping.py 2016-02-25 Rudolf
# subprocess.call() is preferred to os.system()
# works under Python 2.7 and 3.4
# works under Linux, Mac OS, Windows
def ping(host):
"""
Returns True if host responds to a ping request
"""
import subprocess, platform
# Ping parameters as function of OS
ping_str = "-n 1" if platform.system().lower()=="windows" else "-c 1"
args = "ping " + " " + ping_str + " " + host
need_sh = False if platform.system().lower()=="windows" else True
# Ping
return subprocess.call(args, shell=need_sh) == 0
# test call
print(ping("192.168.17.142"))
False if platform.system().lower()=="windows" else True
вы могли, конечно, просто использовать platform.system().lower() != "windows"
.
os.name!="nt"
работает? По общему признанию я не пробовал это на всех вер / платформах!
def ping(host): process = subprocess.Popen(["ping", "-n", "1",host], stdout=subprocess.PIPE, stderr=subprocess.PIPE) streamdata = process.communicate()[0] if 'unreachable' in str(streamdata): return 1 return process.returncode
unreachable
он найден в канале, нет?
После осмотра я написал свой собственный модуль ping, который предназначен для мониторинга большого количества адресов, является асинхронным и не использует много системных ресурсов. Вы можете найти его здесь: https://github.com/romana/multi-ping/ Он лицензирован Apache, поэтому вы можете использовать его в своем проекте любым удобным для вас способом.
Основными причинами реализации моих собственных являются ограничения других подходов:
#!/usr/bin/python3
import subprocess as sp
def ipcheck():
status,result = sp.getstatusoutput("ping -c1 -w2 " + str(pop))
if status == 0:
print("System " + str(pop) + " is UP !")
else:
print("System " + str(pop) + " is DOWN !")
pop = input("Enter the ip address: ")
ipcheck()
Убедитесь, что установлен pyping или установите его pip install pyping
#!/usr/bin/python
import pyping
response = pyping.ping('Your IP')
if response.ret_code == 0:
print("reachable")
else:
print("unreachable")
Программный ICMP-пинг сложен из-за повышенных привилегий, необходимых для отправки необработанных ICMP-пакетов, а вызывающий ping
двоичный код является уродливым. Для мониторинга сервера вы можете достичь того же результата, используя метод TCP ping :
# pip3 install tcping
>>> from tcping import Ping
# Ping(host, port, timeout)
>>> ping = Ping('212.69.63.54', 22, 60)
>>> ping.ping(3)
Connected to 212.69.63.54[:22]: seq=1 time=23.71 ms
Connected to 212.69.63.54[:22]: seq=2 time=24.38 ms
Connected to 212.69.63.54[:22]: seq=3 time=24.00 ms
Внутренне это просто устанавливает TCP-соединение с целевым сервером и немедленно сбрасывает его, измеряя прошедшее время. Эта конкретная реализация немного ограничена в том, что она не обрабатывает закрытые порты, но для ваших собственных серверов она работает довольно хорошо.
Я решаю это с помощью:
def ping(self, host):
res = False
ping_param = "-n 1" if system_name().lower() == "windows" else "-c 1"
resultado = os.popen("ping " + ping_param + " " + host).read()
if "TTL=" in resultado:
res = True
return res
«TTL» - это способ узнать, правильно ли выполнен пинг. Saludos
Мое сокращение - использование идей из ответов в этом посте, но только с использованием более нового рекомендованного модуля подпроцесса и python3:
import subprocess
import platform
operating_sys = platform.system()
nas = '192.168.0.10'
def ping(ip):
# ping_command = ['ping', ip, '-n', '1'] instead of ping_command = ['ping', ip, '-n 1'] for Windows
ping_command = ['ping', ip, '-n', '1'] if operating_sys == 'Windows' else ['ping', ip, '-c 1']
shell_needed = True if operating_sys == 'Windows' else False
ping_output = subprocess.run(ping_command,shell=shell_needed,stdout=subprocess.PIPE)
success = ping_output.returncode
return True if success == 0 else False
out = ping(nas)
print(out)
True if condition else False
для возврата True или False в зависимости от условия. Просто используйте eg shell_needed = operating_sys == 'Windows'
иreturn success == 0
Этот скрипт работает в Windows и должен работать в других ОС: он работает в Windows, Debian и macosx, требуется тестирование на Solaris.
import os
import platform
def isUp(hostname):
giveFeedback = False
if platform.system() == "Windows":
response = os.system("ping "+hostname+" -n 1")
else:
response = os.system("ping -c 1 " + hostname)
isUpBool = False
if response == 0:
if giveFeedback:
print hostname, 'is up!'
isUpBool = True
else:
if giveFeedback:
print hostname, 'is down!'
return isUpBool
print(isUp("example.com")) #Example domain
print(isUp("localhost")) #Your computer
print(isUp("invalid.example.com")) #Unresolvable hostname: https://tools.ietf.org/html/rfc6761
print(isUp("192.168.1.1")) #Pings local router
print(isUp("192.168.1.135")) #Pings a local computer - will differ for your network
Я закончил тем, что нашел этот вопрос относительно похожего сценария. Я попробовал pyping, но пример, приведенный Naveen, не работал для меня в Windows под Python 2.7.
Пример, который работал для меня:
import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")
pyping
не похоже на стандартный модуль. Возможно, вы могли бы предоставить ссылку?
Используя Multi-ping ( pip install multiPing
), я сделал этот простой код ( просто скопируйте и вставьте, если хотите! ):
from multiping import MultiPing
def ping(host,n = 0):
if(n>0):
avg = 0
for i in range (n):
avg += ping(host)
avg = avg/n
# Create a MultiPing object to test hosts / addresses
mp = MultiPing([host])
# Send the pings to those addresses
mp.send()
# With a 1 second timout, wait for responses (may return sooner if all
# results are received).
responses, no_responses = mp.receive(1)
for addr, rtt in responses.items():
RTT = rtt
if no_responses:
# Sending pings once more, but just to those addresses that have not
# responded, yet.
mp.send()
responses, no_responses = mp.receive(1)
RTT = -1
return RTT
Использование:
#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)
Если вы хотите один образец, второй параметр " 10
" можно игнорировать!
Надеюсь, поможет!
Моя версия функции ping:
import platform, subprocess
def ping(host_or_ip, packets=1, timeout=1000):
''' Calls system "ping" command, returns True if ping succeeds.
Required parameter: host_or_ip (str, address of host to ping)
Optional parameters: packets (int, number of retries), timeout (int, ms to wait for response)
Does not show any output, either as popup window or in command line.
Python 3.5+, Windows and Linux compatible (Mac not tested, should work)
'''
# The ping command is the same for Windows and Linux, except for the "number of packets" flag.
if platform.system().lower() == 'windows':
command = ['ping', '-n', str(packets), '-w', str(timeout), host_or_ip]
# run parameters: capture output, discard error messages, do not show window
result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, creationflags=0x08000000)
# 0x0800000 is a windows-only Popen flag to specify that a new process will not create a window.
# On Python 3.7+, you can use a subprocess constant:
# result = subprocess.run(command, capture_output=True, creationflags=subprocess.CREATE_NO_WINDOW)
# On windows 7+, ping returns 0 (ok) when host is not reachable; to be sure host is responding,
# we search the text "TTL=" on the command output. If it's there, the ping really had a response.
return result.returncode == 0 and b'TTL=' in result.stdout
else:
command = ['ping', '-c', str(packets), '-w', str(timeout), host_or_ip]
# run parameters: discard output and error messages
result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return result.returncode == 0
Не стесняйтесь использовать его, как вы будете.
Кажется достаточно простым, но дал мне припадки. Я продолжал получать сообщение «Работа с открытым сокетом ICMP запрещена», иначе решения зависали бы, если бы сервер был отключен. Если, однако, вы хотите знать, что сервер активен и на этом сервере запущен веб-сервер, то curl сделает эту работу. Если у вас есть ssh и сертификаты, то достаточно ssh и простой команды. Вот код:
from easyprocess import EasyProcess # as root: pip install EasyProcess
def ping(ip):
ping="ssh %s date;exit"%(ip) # test ssh alive or
ping="curl -IL %s"%(ip) # test if http alive
response=len(EasyProcess(ping).call(timeout=2).stdout)
return response #integer 0 if no response in 2 seconds
У меня было похожее требование, поэтому я реализовал его, как показано ниже. Он протестирован на 64-битной Windows и Linux.
import subprocess
def systemCommand(Command):
Output = ""
Error = ""
try:
Output = subprocess.check_output(Command,stderr = subprocess.STDOUT,shell='True')
except subprocess.CalledProcessError as e:
#Invalid command raises this exception
Error = e.output
if Output:
Stdout = Output.split("\n")
else:
Stdout = []
if Error:
Stderr = Error.split("\n")
else:
Stderr = []
return (Stdout,Stderr)
#in main
Host = "ip to ping"
NoOfPackets = 2
Timeout = 5000 #in milliseconds
#Command for windows
Command = 'ping -n {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
#Command for linux
#Command = 'ping -c {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
Stdout,Stderr = systemCommand(Command)
if Stdout:
print("Host [{}] is reachable.".format(Host))
else:
print("Host [{}] is unreachable.".format(Host))
Когда IP недоступен, subprocess.check_output () вызывает исключение. Дополнительную проверку можно выполнить путем извлечения информации из строки вывода «Пакеты: отправлено = 2, получено = 2, потеряно = 0 (потеря 0%)».
Вот решение с использованием subprocess
модуля Python и ping
инструмента CLI, предоставляемого базовой ОС. Проверено на Windows и Linux. Поддержка установки таймаута сети. Не нужны права root (по крайней мере, в Windows и Linux).
import platform
import subprocess
def ping(host, network_timeout=3):
"""Send a ping packet to the specified host, using the system "ping" command."""
args = [
'ping'
]
platform_os = platform.system().lower()
if platform_os == 'windows':
args.extend(['-n', '1'])
args.extend(['-w', str(network_timeout * 1000)])
elif platform_os in ('linux', 'darwin'):
args.extend(['-c', '1'])
args.extend(['-W', str(network_timeout)])
else:
raise NotImplemented('Unsupported OS: {}'.format(platform_os))
args.append(host)
try:
if platform_os == 'windows':
output = subprocess.run(args, check=True, universal_newlines=True).stdout
if output and 'TTL' not in output:
return False
else:
subprocess.run(args, check=True)
return True
except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
return False
Используйте это, он протестирован на python 2.7 и работает нормально, он возвращает время проверки в миллисекундах в случае успеха и возвращает False при ошибке.
import platform,subproccess,re
def Ping(hostname,timeout):
if platform.system() == "Windows":
command="ping "+hostname+" -n 1 -w "+str(timeout*1000)
else:
command="ping -i "+str(timeout)+" -c 1 " + hostname
proccess = subprocess.Popen(command, stdout=subprocess.PIPE)
matches=re.match('.*time=([0-9]+)ms.*', proccess.stdout.read(),re.DOTALL)
if matches:
return matches.group(1)
else:
return False
Одна вещь, которую многие ответы упускают, заключается в том, что (по крайней мере, в Windows) ping
команда возвращает 0 (что указывает на успех), если она получает ответ «Узел назначения недоступен».
Вот мой код, который проверяет, есть ли b'TTL='
в ответе, так как он присутствует, только когда пинг достиг хоста. Примечание: большая часть этого кода основана на других ответах здесь.
import platform
import subprocess
def ping(ipAddr, timeout=100):
'''
Send a ping packet to the specified host, using the system ping command.
Accepts ipAddr as string for the ping destination.
Accepts timeout in ms for the ping timeout.
Returns True if ping succeeds otherwise Returns False.
Ping succeeds if it returns 0 and the output includes b'TTL='
'''
if platform.system().lower() == 'windows':
numFlag = '-n'
else:
numFlag = '-c'
completedPing = subprocess.run(['ping', numFlag, '1', '-w', str(timeout), ipAddr],
stdout=subprocess.PIPE, # Capture standard out
stderr=subprocess.STDOUT) # Capture standard error
# print(completedPing.stdout)
return (completedPing.returncode == 0) and (b'TTL=' in completedPing.stdout)
print(ping('google.com'))
Примечание. Это захватывает вывод вместо его печати, поэтому, если вы хотите увидеть вывод ping
, вам нужно будет распечатать completedPing.stdout
перед возвратом.
ТОЛЬКО для WINDOWS - Не могу поверить, что никто не взломал Win32_PingStatus Используя простой WMI-запрос, мы возвращаем объект, полный действительно подробной информации, бесплатно
import wmi
# new WMI object
c = wmi.WMI()
# here is where the ping actually is triggered
x = c.Win32_PingStatus(Address='google.com')
# how big is this thing? - 1 element
print 'length x: ' ,len(x)
#lets look at the object 'WMI Object:\n'
print x
#print out the whole returned object
# only x[0] element has values in it
print '\nPrint Whole Object - can directly reference the field names:\n'
for i in x:
print i
#just a single field in the object - Method 1
print 'Method 1 ( i is actually x[0] ) :'
for i in x:
print 'Response:\t', i.ResponseTime, 'ms'
print 'TTL:\t', i.TimeToLive
#or better yet directly access the field you want
print '\npinged ', x[0].ProtocolAddress, ' and got reply in ', x[0].ResponseTime, 'ms'
Я беру заимствования из других ответов. Попытка упростить и минимизировать запросы.
import platform, os
def ping(host):
result = os.popen(' '.join(("ping", ping.param, host))).read()
return 'TTL=' in result
ping.param = "-n 1" if platform.system().lower() == "windows" else "-c 1"
Мне нужна была более быстрая проверка пинга, и я не хотел использовать какие-либо внешние библиотеки, поэтому я решил использовать параллелизм с использованием встроенного asyncio
.
Этот код требует Python 3.7+ и сделан и протестирован только на Linux . Он не будет работать в Windows, но я уверен, что вы можете легко изменить его для работы в Windows.
Я не эксперт, asyncio
но я использовал эту замечательную статью « Ускорьте вашу программу на Python с параллелизмом» и придумал эти строки кода. Я постарался сделать его максимально простым, поэтому, скорее всего, вам нужно будет добавить в него больше кода, чтобы удовлетворить ваши потребности.
Он не возвращает true или false, я подумал, что было бы удобнее просто напечатать IP-адрес, который отвечает на запрос ping. Я думаю, что это довольно быстро, пинг 255 ips почти за 10 секунд.
#!/usr/bin/python3
import asyncio
async def ping(host):
"""
Prints the hosts that respond to ping request
"""
ping_process = await asyncio.create_subprocess_shell("ping -c 1 " + host + " > /dev/null 2>&1")
await ping_process.wait()
if ping_process.returncode == 0:
print(host)
return
async def ping_all():
tasks = []
for i in range(1,255):
ip = "192.168.1.{}".format(i)
task = asyncio.ensure_future(ping(ip))
tasks.append(task)
await asyncio.gather(*tasks, return_exceptions = True)
asyncio.run(ping_all())
Пример вывода:
192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6
Обратите внимание, что IP-адреса расположены не по порядку, поскольку IP-адрес печатается, как только он отвечает, поэтому тот, который отвечает первым, печатается первым.
1 #!/usr/bin/python
2
3 import os
4 import sys
5 import time
6
7 os.system("clear")
8 home_network = "172.16.23."
9 mine = []
10
11 for i in range(1, 256):
12 z = home_network + str(i)
13 result = os.system("ping -c 1 "+ str(z))
14 os.system("clear")
15 if result == 0:
16 mine.append(z)
17
18 for j in mine:
19 print "host ", j ," is up"
Простой, который я только что приготовил за минуту .. используя icmplib, нужны root-привилегии, приведенные ниже работают довольно хорошо! НТН