回答:
この関数は、任意のOS(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
Windowsの@ikraseによるとTrue
、Destination Host Unreachable
エラーが発生した場合でもこの関数は返されることに注意してください。
説明
このコマンドはping
、WindowsとUnixのようなシステムの両方にあります。
オプション-n
(Windows)または-c
(Unix)は、この例では1に設定されたパケットの数を制御します。
platform.system()
プラットフォーム名を返します。例 'Darwin'
macOS。
subprocess.call()
システムコールを実行します。例 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'オプションを使用して、pingタイムアウト(秒単位)を変更することもできます。これはコンソールにテキストを出力することに注意してください。
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
使い方は非常に簡単ですが、このモジュールを使用する場合は、内部で生のパケットを作成するため、ルートアクセスが必要です。
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')
ソリューションを使用すると、255秒ではなく、1秒で実行されます。さらに、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
、root権限が必要です)があります。
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>> 0.215697261510079666
このモジュールでは、一部のパラメーターのカスタマイズも可能です。
バージョン2.7と3.x、およびプラットフォームLinux、Mac OS、WindowsでPythonプログラムをユニバーサルにしたいので、既存の例を変更する必要がありました。
# 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
パイプで見つかった場合は、むしろ0を返しますか?
周りを見回した後、大量のアドレスを監視するように設計された独自の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は複雑であり、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」は、pingが正しく行われたかどうかを知る方法です。サリュード
この投稿の回答からのアイデアを使用した私の削減ですが、新しい推奨サブプロセスモジュールと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で動作し、他のOSでも動作するはずです。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
私は同様のシナリオに関してこの質問を見つけました。私はパイピングを試しましたが、Naveenによって与えられた例は、Python 2.7のWindowsでは機能しませんでした。
私のために働いた例は:
import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")
pyping
標準モジュールではないようです。おそらくあなたはリンクを提供できますか?
使用してマルチに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)
単一のサンプルが必要な場合は、2番目のパラメーター " 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オープンソケット操作は許可されていません」というメッセージが表示され続けます。そうしないと、サーバーがオフラインの場合にソリューションがハングアップします。ただし、サーバーが稼働していて、そのサーバーでWebサーバーを実行していることを知りたい場合は、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
同様の要件があったので、以下のように実装しました。Windows 64ビットおよび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%損失)」から情報を抽出することで実行できます。
以下は、基礎となるOSが提供するPythonのsubprocess
モジュールと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でテストされ、成功した場合はping時間をミリ秒単位で返し、失敗した場合は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
回答の多くが見落としていることの1つは、(少なくともWindowsでは)ping
コマンドが "Destination host unreachable。"という応答を受け取った場合に0(成功を示す)を返すことです。
b'TTL='
pingがホストに到達したときにのみ存在するため、応答にあるかどうかを確認する私のコードは次のとおりです。注:このコードのほとんどは、ここでの他の回答に基づいています。
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"
より高速なpingスイープが必要で、外部ライブラリを使用したくなかったため、組み込みを使用して同時実行を使用することにしましたasyncio
。
このコードはpython 3.7以降を必要とし、Linuxでのみ作成およびテストされています。Windowsでは動作しませんが、Windowsで動作するように簡単に変更できると思います。
私はエキスパートではありませんが、asyncio
このすばらしい記事「同時実行によるPythonプログラムのスピードアップ」を使用して、これらのコード行を思いつきました。できる限りシンプルにするように心がけたので、ニーズに合わせてコードを追加する必要があります。
trueまたはfalseを返さないので、pingリクエストに応答するIPを出力するだけの方が便利だと思いました。私はそれがかなり速いと思います、ほぼ10秒で255 ipsをpingします。
#!/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が順番になっていないことに注意してください。最初に応答した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"
シンプルなものは私がすぐに調理しました。HTH