(With Windows 10)
Consider using the subprocess
module, like so:
>>> import os, subprocess
>>> startupinfo = subprocess.STARTUPINFO()
>>> startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
>>> with subprocess.Popen("ping 192.168.1.1", startupinfo=startupinfo, text=True, stdout=subprocess.PIPE) as p:
for line in p.stdout:
print(line, end="")
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Ping statistics for 192.168.1.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
>>> with subprocess.Popen("ping 10.1.10.1", startupinfo=startupinfo, text=True, stdout=subprocess.PIPE) as p:
for line in p.stdout:
print(line, end="")
Pinging 10.1.10.1 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Ping statistics for 10.1.10.1:
Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
Iterate over p.stdout
to get each line of the results as a string. Obviously you can ignore this if you want, in which case the text
and stdout
arguments can be removed.
Use p.returncode
to get the return code.
On my Windows 10 machine, ping
returns 0 if it receives a reply, and 1 if there's an error. Note that it returns 0 when I receive a Destination host unreachable response after trying to ping an address on my LAN that doesn't exist. Though I doubt it'll be an issue for your use case.
p.returncode
will return None
if you access it before the process has ended.
You can wait for the process to end by calling the p.wait()
method, like so:
with subprocess.Popen("ping 192.168.1.1", startupinfo=startupinfo, text=True, stdout=subprocess.PIPE) as p:
p.wait()
print("Return code for 192.168.1.1:", p.returncode)
for line in p.stdout:
print(line, end="") # This will now all print immediately, after waiting for the process to finish
Output:
Return code for 192.168.1.1: 0
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Ping statistics for 192.168.1.1:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
Or you can access p.returncode
after the with
statement, like so:
with subprocess.Popen("ping 10.1.10.1", startupinfo=startupinfo, text=True, stdout=subprocess.PIPE) as p:
for line in p.stdout:
print(line, end="")
print("Return code for 10.1.10.1:", p.returncode)
Output:
Pinging 10.1.10.1 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Ping statistics for 10.1.10.1:
Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
Return code for 10.1.10.1: 1
Pinging a non-existant address on my LAN returns 0:
with subprocess.Popen("ping 192.168.1.99", startupinfo=startupinfo, text=True, stdout=subprocess.PIPE) as p:
for line in p.stdout:
print(line, end="")
print("Return code for 192.168.1.99:", p.returncode)
Output:
Pinging 192.168.1.99 with 32 bytes of data:
Reply from 192.168.1.105: Destination host unreachable.
Reply from 192.168.1.105: Destination host unreachable.
Reply from 192.168.1.105: Destination host unreachable.
Reply from 192.168.1.105: Destination host unreachable.
Ping statistics for 192.168.1.99:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Return code for 192.168.1.99: 0
Pinging an invalid URL returns 1:
with subprocess.Popen("ping www..com", startupinfo=startupinfo, text=True, stdout=subprocess.PIPE) as p:
for line in p.stdout:
print(line, end="")
print("Return code for www..com:", p.returncode)
Output:
Ping request could not find host www..com. Please check the name and try again.
Return code for www..com: 1