0

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?

5
  • possible duplicate of this? stackoverflow.com/questions/24849998/… Commented May 18, 2019 at 21:09
  • @AkhilBatra Not quite, I still want my custom error to print when the file doesn't exist, instead of just returning an error from cmd Commented May 18, 2019 at 21:11
  • you can try redirecting subprocess output to stderr and catch error based on the return code. Similar to this - stackoverflow.com/questions/16198546/… Commented May 18, 2019 at 21:17
  • @AkhilBatra I get error code 2 both times when returning the error using except OSError as ex print(ex) Commented May 18, 2019 at 21:22
  • That's a bummer. Commented May 18, 2019 at 21:24

2 Answers 2

1

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)
Sign up to request clarification or add additional context in comments.

Comments

1

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

2 Comments

you can capture the output with this python except OSError as ex: python print(ex)
problem is, with this one, you end up with everything inputted into something like cmd or python being treated as an input into my terminal

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.