Pranav Pednekar
Pranav Pednekar

Reputation: 43

Python wrapper around ping command to stop when pong was received

I have a server that I send 4 ICMP pings to using Python. My code looks like this:

command = ['ping', '-c', '4', '192.168.1.8']
proc = subprocess.run(command)
if proc.returncode == 0:
    print("Alive")
else:
    print("Dead")

In this code, each time 4 ping requests will be sent out and only after receiving the reply from all 4 will the return code be checked. However, the modification that I want to make is as soon as any one of the ping requests succeed, I want to immediately declare it as "Alive" and move on. If all 4 fail, then we mark the server as "Dead". The reason I want to make this modification is that I am pinging a lot of servers and waiting for 4 replies from each server when the first successful reply means its alive makes the script run longer. I believe this modification will make the script complete faster. How can I achieve this?

Upvotes: 3

Views: 718

Answers (1)

fuenfundachtzig
fuenfundachtzig

Reputation: 8352

Rather than trying to stop an external process based on its output, why not just do one ping at a time and implement the loop yourself:

max_tries = 4
for _ in range(max_tries):
  command = ['ping', '-w', '1', '-c', '1', 'localhost'] 
  proc = subprocess.run(command) 
  if proc.returncode == 0: 
    print("Alive") 
    break 
else: 
  print("Dead") 

The else clause will only be executed if the end of the for loop is reached, i.e. no reply was received. Modify the timeout (-w) to suit your needs.

The ping command by itself does not provide an option to stop early when a reply is received. So you would have to capture its output and kill the process, which is not elegant and has a lot of room for potential failures.

Upvotes: 1

Related Questions