Auxilor
Auxilor

Reputation: 109

How to distinguish between subprocess errors in python?

I'm working on a terminal that can call other programs like any other terminal. I'm using subprocess for it, on Windows. I'm running into 2 issues.

First: Currently, I'm using OSError for all errors raised when using subprocess.Popen.

The code for it is here:

try:
    subprocess.Popen([command])
except OSError:
    print("'" + command[0] + "' is not recognised as a command, program or bterm file.")

When I type python, it opens command-line python correctly. When I type asdfa, it returns the error. The problem is, when I type python non-existent-file.py I get the same error, when the child argument was the issue.

I want the terminal to return (null): can't open file 'test': [Errno 2] No such file or directory like when it's called from cmd or bash.

How can I distinguish between these 2 errors, while keeping my custom error message for when the file doesn't exist?

Second: Whenever I pass multi-word args into subprocess.Popen or subprocess.call I automatically get that error, which I don't get using os.system()

I don't want to use os.system because I can't raise custom errors with it.

What am I doing wrong?

Upvotes: 0

Views: 1023

Answers (2)

0x76
0x76

Reputation: 185

You could test for the existence of the executable first with the help of shutil.which.

if shutil.which(commands[0]):
    try:
        subprocess.Popen([commands])
    except OSError as err:
        print(err)
else:
    print("'{}' is not recognised as a command, program or bterm file.".format(commands[0])

The documentation has a great deal of info however: https://docs.python.org/dev/library/subprocess.html which may be helpful.

Edit: showed how to capture output, thanks to Auxilor

Upvotes: 1

shyamzzp
shyamzzp

Reputation: 145

Exceptions in subprocess calls:

Exceptions raised in the child process, before the new program has started to execute, will be re-raised in the parent. Additionally, the exception object will have one extra attribute called child_traceback, which is a string containing traceback information from the child’s point of view.

The most common exception raised is OSError. This occurs, for example, when trying to execute a non-existent file. Applications should prepare for OSError exceptions.

A ValueError will be raised if Popen is called with invalid arguments.

check_call() and check_output() will raise CalledProcessError if the called process returns a non-zero return code.

You can find more at: https://docs.python.org/2/library/subprocess.html#exceptions

As well as you can find the Exception Heirarchy at: https://docs.python.org/2/library/exceptions.html#exception-hierarchy

try:
    output = subprocess.check_output("\\test.exe')
except subprocess.CalledProcessError as e:
    print("Something Fishy... returncode: " + e.returncode + ", output:\n" + e.output)
else:
    print("Working Fine:\n" + output)

Upvotes: 1

Related Questions