Testing Host Reachability with Python

The 'ping' command is a utility that tests the reachability of a host over an IP network, such as a Local Area Network (LAN), or the Internet. It uses Internet Control Message Protocol (ICMP) echo request messages to contact the host and corresponding replies are received if the host is reachable. By default, in Windows, four echo request messages are sent, so four responses should be received. Included with each response is the corresponding IP address, the round-trip time in milliseconds and the time to live (TTL), which signifies how many hops it took to reach the destination. For Unix-like operating systems, such as Linux and macOS, echo requests continue to be sent until the command is aborted. This is achieved with Control+C in Linux and Command+C in macOS. Simple usage from the command line, without specifying the number of echo requests, or any other options is as follows.

ping www.stuartsplace.com

It should be noted that this will also work with an IP address.

Python can be used to issue ping commands. This may be useful for automating the process, particularly if the result needs to be recorded, or there are a number of hosts that need to be checked.

import subprocess

# Host to ping.
host = "www.stuartsplace.com"

# Define the command and arguments.
command = ['ping', host]

# Execute the command and capture the output.
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# Check if the ping was successful.
if result.returncode == 0:
    print(f"The host '{host}' is reachable:")
else:
    print(f"The host '{host}' is not reachable:")

# print the result.
print(f"{result.stdout}")

The above example on Windows will issue four echo requests and if successful get four responses back. Unlike when running 'ping' directly on the command line, this won't work on Unix-like operating systems without explicitly specifying the number of echo requests to make.

import subprocess

# Host to ping.
host = "www.stuartsplace.com"

# Define the command and arguments.
command = ['ping', '/n', '4', host]

# Execute the command and capture the output.
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# Check if the ping was successful.
if result.returncode == 0:
    print(f"The host '{host}' is reachable:")
else:
    print(f"The host '{host}' is not reachable:")

# print the result.
print(f"{result.stdout}")

Here, the '/n' option, with the number '4' is added on Windows to the command arguments to explicitly state that four echo requests need to be made.

On Unix-like operating systems the options are specified slightly differently, with the '-c' option needing to be used rather than '/n' to achieve the same result.

import subprocess

# Host to ping.
host = "www.stuartsplace.com"

# Define the command and arguments.
command = ['ping', '-c', '4', host]

# Execute the command and capture the output.
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# Check if the ping was successful.
if result.returncode == 0:
    print(f"The host '{host}' is reachable:")
else:
    print(f"The host '{host}' is not reachable:")

# print the result.
print(f"{result.stdout}")

Rather than writing a slightly different script depending on the operating system it is being run on, a check could be made for the operating system so that the right option is specified.

import platform
import subprocess

# Host to ping.
host = "www.stuartsplace.com"

# Check the operating system to specify correct option.
param = '/n' if platform.system().lower() == 'windows' else '-c'

# Define the command and arguments.
command = ['ping', param, '4', host]

# Execute the command and capture the output.
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# Check if the ping was successful.
if result.returncode == 0:
    print(f"The host '{host}' is reachable:")
else:
    print(f"The host '{host}' is not reachable:")

# print the result.
print(f"{result.stdout}")

In the same way that the an IP address, rather than a web address, can be specified when 'ping' is run from the command line, an IP address can also be specified when using Python. Here, the IP addres of one of Google's DNS servers is used.

import platform
import subprocess

# Host to ping.
host = "8.8.8.8"

# Check the operating system to specify correct option.
param = '/n' if platform.system().lower() == 'windows' else '-c'

# Define the command and arguments.
command = ['ping', param, '4', host]

# Execute the command and capture the output.
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# Check if the ping was successful.
if result.returncode == 0:
    print(f"The host '{host}' is reachable:")
else:
    print(f"The host '{host}' is not reachable:")

# print the result.
print(f"{result.stdout}")