check output from CalledProcessError
I ran into the same problem and found that the documentation has example for this type of scenario (where we write STDERR TO STDOUT and always exit successfully with return code 0) without causing/catching an exception.
output = subprocess.check_output("ping -c 2 -W 2 1.1.1.1; exit 0", stderr=subprocess.STDOUT, shell=True)
Now, you can use standard string function find
to check the output string output
.
In the list of arguments, each entry must be on its own. Using
output = subprocess.check_output(["ping", "-c","2", "-W","2", "1.1.1.1"])
should fix your problem.
According to the Python os module documentation os.popen has been deprecated since Python 2.6.
I think the solution for modern Python is to use check_output() from the subprocess module.
From the subprocess Python documentation:
subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False) Run command with arguments and return its output as a byte string.
If the return code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and any output in the output attribute.
If you run through the following code in Python 2.7 (or later):
import subprocess
try:
print subprocess.check_output(["ping", "-n", "2", "-w", "2", "1.1.1.1"])
except subprocess.CalledProcessError, e:
print "Ping stdout output:\n", e.output
You should see an output that looks something like this:
Ping stdout output:
Pinging 1.1.1.1 with 32 bytes of data:
Request timed out.
Request timed out.
Ping statistics for 1.1.1.1:
Packets: Sent = 2, Received = 0, Lost = 2 (100% loss),
The e.output string can be parsed to suit the OPs needs.
If you want the returncode or other attributes, they are in CalledProccessError as can be seen by stepping through with pdb
(Pdb)!dir(e)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
'__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__',
'__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__',
'__unicode__', '__weakref__', 'args', 'cmd', 'message', 'output', 'returncode']
If you want to get stdout and stderr back (including extracting it from the CalledProcessError in the event that one occurs), use the following:
import subprocess
def call_with_output(command):
success = False
try:
output = subprocess.check_output(command, stderr=subprocess.STDOUT).decode()
success = True
except subprocess.CalledProcessError as e:
output = e.output.decode()
except Exception as e:
# check_call can raise other exceptions, such as FileNotFoundError
output = str(e)
return(success, output)
call_with_output(["ls", "-l"])
This is Python 2 and 3 compatible.
If your command is a string rather than an array, prefix this with:
import shlex
call_with_output(shlex.split(command))