Search code examples
bashsubprocesspython-3.7

Python subprocess check_call: How to assign the non-0 exit code to a variable rather than raising an exception?


output = subprocess.check_call('invented_command', shell=True)  # Returns 127

This code raise an exception (as explained in the manual) with 127 instead of assign 127 to the "output" variable, which remains unassigned. Only if the exit code is equal to 0, the "output" variable is set.


Solution

  • The very definition of check_call is that it will raise an exception if the call fails; that's what the check part checks.

    Its sibling subprocess.call(), without the check, does exactly what you are asking for, though, and returns the result code directly, and is available all the way back to Python 2.4 (which is when subprocess was introduced).

    With Python 3.5+ you can replace check_call and call (as well as check_output) with run with suitable parameters. For this specific case it's slightly more complicated, but if you need anything more than just the basics, it's a better and more versatile starting point for writing a wrapper of your own.

    result = subprocess.run(['invented_command'])  # check=True to enable check
    status_code = result.returncode
    

    Notice also how I changed the wrapper to avoid shell=True which seemed superfluous here; if your actual invented command really requires a shell for some reason, obviously take out the [...] around the command and add back the pesky shell=True (or, better yet, find a way to avoid it by other means).