Reputation: 12500
I am using:
grepOut = subprocess.check_output("grep " + search + " tmp", shell=True)
To run a terminal command, I know that I can use a try/except to catch the error but how can I get the value of the error code?
I found this on the official documentation:
exception subprocess.CalledProcessError
Exception raised when a process run by check_call() or check_output() returns a non-zero exit status.
returncode
Exit status of the child process.
But there are no examples given and Google was of no help.
Upvotes: 84
Views: 168256
Reputation: 115
Note that since Python 3.5 it is better to use subprocess.run() :
import subprocess
grepOut = subprocess.run(['grep', search, 'tmp'], shell=True) ## Only use shell=True if necessary
This will generate a subprocess.CompletedProcess
instance which will be stored at grepOut
. Then, and finally answering your question, you can get the return value from subprocess.run()
like this:
grepOut.returncode
which will be equal to 0
if the command was successful, and not equal to 0
if it failed.
Finally, for completeness sake, you could even handle the error by means of a try/except block using the method check_returncode() from subprocess.CompletedProcess
class:
try:
## Add argument `capture_output=True` if you want to store the output of the command
grepOut = subprocess.run(['grep', search, 'tmp'], shell=True)
grepOut.check_returncode()
except subprocess.CalledProcessError as err:
## If returncode is non-zero, raise a CalledProcessError and print this message
print(f"Oops, something went wrong. Error code: {err.returncode}")
Hope it is clear enough.
Upvotes: 4
Reputation: 3078
You can get the error code and results from the exception that is raised.
This can be done through the fields returncode
and output
.
For example:
import subprocess
try:
grepOut = subprocess.check_output("grep " + "test" + " tmp", shell=True)
except subprocess.CalledProcessError as grepexc:
print("error code", grepexc.returncode, grepexc.output)
Upvotes: 101
Reputation: 16971
In Python 2 - use commands module:
import command
rc, out = commands.getstatusoutput("ls missing-file")
if rc != 0: print "Error occurred: %s" % out
In Python 3 - use subprocess module:
import subprocess
rc, out = subprocess.getstatusoutput("ls missing-file")
if rc != 0: print ("Error occurred:", out)
Error occurred: ls: cannot access missing-file: No such file or directory
Upvotes: 2
Reputation: 69
To get both output and return code (without try/except) simply use subprocess.getstatusoutput (Python 3 required)
Upvotes: 4
Reputation: 47239
Python 3.5 introduced the subprocess.run()
method. The signature looks like:
subprocess.run(
args,
*,
stdin=None,
input=None,
stdout=None,
stderr=None,
shell=False,
timeout=None,
check=False
)
The returned result is a subprocess.CompletedProcess
. In 3.5, you can access the args
, returncode
, stdout
, and stderr
from the executed process.
Example:
>>> result = subprocess.run(['ls', '/tmp'], stdout=subprocess.DEVNULL)
>>> result.returncode
0
>>> result = subprocess.run(['ls', '/nonexistent'], stderr=subprocess.DEVNULL)
>>> result.returncode
2
Upvotes: 54
Reputation: 414079
is there a way to get a return code without a try/except?
check_output
raises an exception if it receives non-zero exit status because it frequently means that a command failed. grep
may return non-zero exit status even if there is no error -- you could use .communicate()
in this case:
from subprocess import Popen, PIPE
pattern, filename = 'test', 'tmp'
p = Popen(['grep', pattern, filename], stdin=PIPE, stdout=PIPE, stderr=PIPE,
bufsize=-1)
output, error = p.communicate()
if p.returncode == 0:
print('%r is found in %s: %r' % (pattern, filename, output))
elif p.returncode == 1:
print('%r is NOT found in %s: %r' % (pattern, filename, output))
else:
assert p.returncode > 1
print('error occurred: %r' % (error,))
You don't need to call an external command to filter lines, you could do it in pure Python:
with open('tmp') as file:
for line in file:
if 'test' in line:
print line,
If you don't need the output; you could use subprocess.call()
:
import os
from subprocess import call
try:
from subprocess import DEVNULL # Python 3
except ImportError: # Python 2
DEVNULL = open(os.devnull, 'r+b', 0)
returncode = call(['grep', 'test', 'tmp'],
stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL)
Upvotes: 37