Reputation: 3915
I am using the subprocess
module and check_output()
to create a virtual shell in my Python script, and it works fine for commands that return a zero exit status, however for ones that don't it returns an exception without printing the error that would have been displayed in the output on a normal shell.
For instance, I would expect something to work like this:
>>> shell('cat non-existing-file')
cat: non-existing-file: No such file or directory
But instead, this happens:
>>> shell('cat non-existing-file')
CalledProcessError: Command 'cat non-existing-file' returned non-zero exit status 1 (file "/usr/lib/python2.7/subprocess.py", line 544, in check_output)
Even though I could remove the Python exception message using try
and except
, I still want the cat: non-existing-file: No such file or directory
to display to the user.
How would I go about doing this?
shell()
:
def shell(command):
output = subprocess.check_output(command, shell=True)
finished = output.split('\n')
for line in finished:
print line
return
Upvotes: 18
Views: 31352
Reputation: 86
How about using subprocess.run()
import subprocess
output = subprocess.run(['cat', 'non-existing-file'], stdout = subprocess.PIPE, stderr=subprocess.PIPE)
print (output.stderr.decode())
Here is the output
> python3 file.py
cat: non-existing-file: No such file or directory
Upvotes: 0
Reputation: 38253
If you're using Python 3.5+, you can run it with check=False
:
subprocess.run("exit 1", shell=True, check=False)
If check is true, and the process exits with a non-zero exit code, a CalledProcessError exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.
For older Python 3 versions, there's different methods for checking vs not checking the call.
To get the output, just pass capture_output=True
and then get stdout
value from CompletedProcess
Upvotes: 4
Reputation: 1207
Something like this perhaps?
def shell(command):
try:
output = subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT)
except Exception, e:
output = str(e.output)
finished = output.split('\n')
for line in finished:
print line
return
Upvotes: 21