user1447941
user1447941

Reputation: 3915

Ignoring CalledProcessError

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

Answers (3)

kishore
kishore

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

Alex W
Alex W

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

smang
smang

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

Related Questions