Python: execute ping as subprocess with timeout
Hi,
I have to measure RTT between several hosts in Internet. In python there are several libraries, however they require root access. For this reason I wrote a simple function that call system ping and parse the output.
Code:
for host in tqdm(hosts):
ping=subprocess.Popen(["ping", "-c", "1", "-w", "0.2", host],stdout=subprocess.PIPE, stderr = subprocess.PIPE)
[out, err]=ping.communicate()
if ping.returncode == 0:
avgRTT=re.search("rtt min/avg/max/mdev = (\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)", str(out)).group(1)
I want to ping an host and timeout if it last over 200 ms (200 ms is the minimum value without having root access).
From man ping, I read that the options -w deadline and -W timeout should do the job, but they does not work as aspected if an host is unreachable.
I already read here and the only solution is to use fping that is not portable.
Thank you
Re: Python: execute ping as subprocess with timeout
Hi,
I solved by myself with the following code:
Code:
for host in tqdm(hosts):
ping=subprocess.Popen(["ping", "-c", "1", proxy[0]],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
try:
[out, err]=ping.communicate(timeout=0.1)
if ping.returncode == 0:
avgRTT=re.search("rtt min/avg/max/mdev = (\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)", str(out)).group(1)
except subprocess.TimeoutExpired:
ping.kill()
The only problem is that I have to use python3.3+ since even by installing subprocess32 does not work for me.
Re: Python: execute ping as subprocess with timeout
Hai,
I tried this one, it worked out for me.
import subprocess
from threading import Timer
kill = lambda process: process.kill()
cmd = ['ping', 'www.google.com']
ping = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
my_timer = Timer(5, kill, [ping])
try:
my_timer.start()
stdout, stderr = ping.communicate()
finally:
my_timer.cancel()
I used the python 3.3 it works fine.
Thank you,
Riya
Re: Python: execute ping as subprocess with timeout
Thank you of your answer of course your solution works for python3.3+ as the mine.
I think I will use only python3.3+. Moreover, I modified the script in order to work for different operating system.
Code:
for host in tqdm(hosts):
if platform == "linux" or platform == "darwin":
command=["ping", "-c", "3", "-i", "0.2", host]
timeout=0.5
else:
command=["ping", "-n", "1", host]
timeout=0.2
ping=subprocess.Popen(command,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
try:
[out, err]=proc.communicate(timeout=2.1)
if proc.returncode == 0:
if platform == "linux" or platform == "darwin":
avgRTT=re.search("rtt min/avg/max/mdev = (\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)", str(out)).group(2)
else:
# to do
avgRTT=re.search("", str(out))
Unfortunately, windows has different ping version than GNU/linux or mac os X that does not support the option -i and so I have to play with timeout in order to limit the time required.
Moreover, also the parsing is different.