I am writing a Python script to calculate packet loss through pinging an IP address using subprocess module in Linux. More than one IP address is kept in my CSV file.
It is running fine when the pingable destination are only given. But throwing an error when there is a non-pingable IP given in the CSV file and then the script is exiting without checking the other IP address in that CSV file. So I am not able to capture the packet loss for the non-pingable destination which is the main purpose the script.
subprocess.check_output(['ping','-c 4',hostname], shell=False,
universal_newlines=True).splitlines()
Error:
subprocess.CalledProcessError: Command '['ping', '-c 4', '192.168.134.100']' returned non-zero exit status 1
We have to capture the exception from the subprocess.CalledProcessError when the IP is not reachable or the given Subprocess argument has an issue.
Original code:
hostname = '1.0.2.1'
output = subprocess.check_output(['ping', '-c 4', hostname], shell=False, universal_newlines=True).splitlines() print(f"check_output - output:\n{output}")
Exception like this when the subprocess fails:
Traceback (most recent call last):
File "/Users/muthukumar/Documents/PythonScript/logics/SubProcesssExecution.py", line 136, in <module>
output = subprocess.check_output(['ping', '-c 4', hostname], shell=False, universal_newlines=True).splitlines()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/subprocess.py", line 466, in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/subprocess.py", line 571, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['ping', '-c 4', '1.0.2.1']' returned non-zero exit status 2.
Add a try/except block to capture the CalledProcessError
hostname = '1.0.2.1'
try:
output = subprocess.check_output(['ping', '-c 4', hostname], universal_newlines=True).splitlines()
print(f"check_output - output:\n{output}")
except subprocess.CalledProcessError as e:
# This will catch non-zero exit codes from the ping command
print(f"Ping failed with status code {e.returncode}.")
print(f"Error output: {e.output}")
except Exception as Err:
# This will catch other exceptions
print(f"An error occurred: {Err}")
Console Output:
Ping failed with status code 2.
Error output: PING 1.0.2.1 (1.0.2.1): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
--- 1.0.2.1 ping statistics ---
4 packets transmitted, 0 packets received, 100.0% packet loss
When the subprocess successfully executes the given command(s)
hostname = 'google.com'
try:
output = subprocess.check_output(['ping', '-c 4', hostname], universal_newlines=True).splitlines()
print(f"check_output - output:\n{output}")
except subprocess.CalledProcessError as e:
# This will catch non-zero exit codes from the ping command
print(f"Ping failed with status code {e.returncode}.")
print(f"Error output: {e.output}")
except Exception as Err:
# This will catch other exceptions
print(f"An error occurred: {Err}")
Console Output:
check_output - output:
['PING google.com (142.250.193.174): 56 data bytes', '64 bytes from 142.250.193.174: icmp_seq=0 ttl=118 time=17.886 ms', '64 bytes from 142.250.193.174: icmp_seq=1 ttl=118 time=10.396 ms', '64 bytes from 142.250.193.174: icmp_seq=2 ttl=118 time=13.658 ms', '64 bytes from 142.250.193.174: icmp_seq=3 ttl=118 time=13.682 ms', '', '--- google.com ping statistics ---', '4 packets transmitted, 4 packets received, 0.0% packet loss', 'round-trip min/avg/max/stddev = 10.396/13.905/17.886/2.659 ms']
It is just that subprocess returns an error if your ping has 100% packet loss, destination unreachable or any other problem. What you could do is:
try:
# subprocess code here
except:
# some code here if the destination is not pingable, e.g. print("Destination unreachable..") or something else
pass # You need pass so the script will continue on even after the error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With