2019/09/16(月) [n年前の日記]
#2 [python] pythonでpingを打つスクリプト
無線LAN子機がLAN接続できていた時間を計るために、Pythonでスクリプトを書いてみたり。1秒毎にpingを打って、反応が無かったら繋がっていた時間を表示して終了、みたいな。せっかくだから curses を使って、時間表示もするようにしてみたり。
動作環境は、Windows10 x64 + Python 2.7.16 32bit + curses。
curses を使うと、端末上の好きな位置に文字列を表示できる。Windows版Python には標準で入ってなかった記憶があるので、以下から curses-2.2.1+utf8-cp27-cp27m-win32.whl を入手してインストールさせてもらった。ありがたや。
_Python Extension Packages for Windows - Christoph Gohlke
今回書いたスクリプトは以下。
_ping_monitor.py
使い方は以下。
実行中に、qキーかESCキーを押せば途中で終了できる。
動作環境は、Windows10 x64 + Python 2.7.16 32bit + curses。
curses を使うと、端末上の好きな位置に文字列を表示できる。Windows版Python には標準で入ってなかった記憶があるので、以下から curses-2.2.1+utf8-cp27-cp27m-win32.whl を入手してインストールさせてもらった。ありがたや。
_Python Extension Packages for Windows - Christoph Gohlke
pip install curses-2.2.1+utf8-cp27-cp27m-win32.whl
今回書いたスクリプトは以下。
_ping_monitor.py
"""
display time and ping send.
Windows10 x64 + Python 2.7.16 32bit
"""
import subprocess
import curses
import os
import time
from datetime import datetime
import sys
import argparse
def is_connectable(host):
"""Ping."""
copt = "-c"
tmout = "3"
if os.name == "nt":
# Windows NT
copt = "-n"
tmout = "3000"
ping = subprocess.Popen(
["ping", "-w", tmout, copt, "1", host],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE
)
ping.communicate()
return ping.returncode == 0
def get_hms(t):
"""Get HH:MM:SS."""
h = int(t / 3600)
m = int((t / 60) % 60)
s = int(t % 60)
return h, m, s
def win_main(win):
"""Main."""
curses.curs_set(0)
win.nodelay(True)
key = ""
win.clear()
tm = time.time()
while True:
n = time.time()
t = "%s" % datetime.fromtimestamp(n)
win.addstr(0, 0, starttimestr)
d = n - tm
if d >= 1.0:
win.addstr(3, 0, "ping")
result = is_connectable(host)
if result is not True:
win.addstr(1, 0, "%s - %s is dead." % (t, host))
break
else:
win.addstr(1, 0, "%s - %s is alive." % (t, host))
h, m, s = get_hms(n - starttime)
win.addstr(2, 0, "%d:%02d:%02d" % (h, m, s))
tm = time.time()
elif d >= 0.4:
win.move(3, 0)
win.clrtoeol()
try:
key = win.getkey()
if key == os.linesep or key == "q" or ord(key) == 27:
break
except Exception as e:
# No input
pass
time.sleep(0.2)
parser = argparse.ArgumentParser(description="Send ping.")
parser.add_argument("hostname", metavar="HOSTNAME", help="host name")
args = parser.parse_args()
host = args.hostname
starttime = time.time()
starttimestr = "%s - start" % datetime.fromtimestamp(starttime)
curses.wrapper(win_main)
print(starttimestr)
endtime = time.time()
t = "%s" % datetime.fromtimestamp(endtime)
print("%s - %s is dead." % (t, host))
h, m, s = get_hms(endtime - starttime)
print("%d:%02d:%02d" % (h, m, s))
sys.exit()
使い方は以下。
python ping_monitor.py HOSTNAME
実行中に、qキーかESCキーを押せば途中で終了できる。
◎ 参考ページ。 :
以下、参考ページ。
_pythonでping監視 - 雑食へいちゃんの思い出達
_ping疎通確認結果を機械的に判定する - Qiita
_【Python】ping試験でサーバーの死活監視 | 西住工房@技術雑記
_Pythonでキー入力を用いてLoopを抜けるには? - Qiita
_Pythonで、cursesモジュールを使う - naritoブログ
_pythonでping監視 - 雑食へいちゃんの思い出達
_ping疎通確認結果を機械的に判定する - Qiita
_【Python】ping試験でサーバーの死活監視 | 西住工房@技術雑記
_Pythonでキー入力を用いてLoopを抜けるには? - Qiita
_Pythonで、cursesモジュールを使う - naritoブログ
◎ 気づいた点をメモ。 :
一般的にこの手のスクリプトは *NIX上で動かすことを前提にしているようで、ping に渡すオプションも *NIX版の ping に合わせている事例が多いっぽい。ただ、Windowsに標準で入っている ping は、オプション指定が違うわけで。
- 回数の指定 : *NIX は -c N。Windows は -n N。
- タイムアウト値 : *NIX は秒。Windows はミリ秒。
[ ツッコむ ]
以上です。