I want to call ping
from Python and get the output. I tried the following:
response = os.system(\"ping \"+ \"- c\")
However,
If you only need to check if the ping was successful, look at the status code; ping
returns 2
for a failed ping, 0
for a success.
I'd use subprocess.Popen() (and not subprocess.check_call()
as that raises an exception when ping
reports the host is down, complicating handling). Redirect stdout
to a pipe so you can read it from Python:
ipaddress = '198.252.206.140' # guess who
proc = subprocess.Popen(
['ping', '-c', '3', ipaddress],
stdout=subprocess.PIPE)
stdout, stderr = proc.communicate()
if proc.returncode == 0:
print('{} is UP'.format(ipaddress))
print('ping output:')
print(stdout.decode('ASCII'))
You can switch to subprocess.DEVNULL* if you want to ignore the output; use proc.wait()
to wait for ping
to exit; you can add -q
to have ping
do less work, as it'll produce less output with that switch:
proc = subprocess.Popen(
['ping', '-q', '-c', '3', ipaddress],
stdout=subprocess.DEVNULL)
proc.wait()
if proc.returncode == 0:
print('{} is UP'.format(ipaddress))
In both cases, proc.returncode
can tell you more about why the ping failed, depending on your ping
implementation. See man ping
for details. On OS X the manpage states:
EXIT STATUS
The ping utility exits with one of the following values:
0 At least one response was heard from the specified host.
2 The transmission was successful but no responses were received.
any other value
An error occurred. These values are defined in <sysexits.h>.
and man sysexits
lists further error codes.
The latter form (ignoring the output) can be simplified by using subprocess.call(), which combines the proc.wait()
with a proc.returncode
return:
status = subprocess.call(
['ping', '-q', '-c', '3', ipaddress],
stdout=subprocess.DEVNULL)
if status == 0:
print('{} is UP'.format(ipaddress))
* subprocess.DEVNULL
is new in Python 3.3; use open(os.devnull, 'wb')
in it's place in older Python versions, making use of the os.devnull value, e.g.:
status = subprocess.call(
['ping', '-q', '-c', '3', ipaddress],
stdout=open(os.devnull, 'wb'))
To get the output of a command, use subprocess.check_output. It raises an error if the command fails, so surround it in a try
block.
import subprocess
try:
response = subprocess.check_output(
['ping', '-c', '3', '10.10.0.100'],
stderr=subprocess.STDOUT, # get all output
universal_newlines=True # return string not bytes
)
except subprocess.CalledProcessError:
response = None
To use ping
to know whether an address is responding, use its return value, which is 0 for success. subprocess.check_call will raise and error if the return value is not 0. To suppress output, redirect stdout
and stderr
. With Python 3 you can use subprocess.DEVNULL
rather than opening the null file in a block.
import os
import subprocess
with open(os.devnull, 'w') as DEVNULL:
try:
subprocess.check_call(
['ping', '-c', '3', '10.10.0.100'],
stdout=DEVNULL, # suppress output
stderr=DEVNULL
)
is_up = True
except subprocess.CalledProcessError:
is_up = False
In general, use subprocess
calls, which, as the docs describe, are intended to replace os.system
.