Search code examples
pythonsubprocess

subprocess check_output throws exception without any error message


When I run clang main.cpp -o myprogram.exe in the terminal I get a meaningful error message:

main.cpp:6:32: error: expected ';' after expression
    std::cout << "Hello World!"

but when I try to reproduce it using python and running

try:
    subprocess.check_output('clang main.cpp -o myprogram.exe')
except subprocess.CalledProcessError as e:
    print(e)
    print(e.output)
    print(e.stderr)
    print(e.stdout)
Command 'clang main.cpp -o myprogram.exe' returned non-zero exit status 1.
b''
None
b''

How can I give my user back the same error message the terminal provides?


Solution

  • Based on the Python docs, subprocess.check_output(...) is equivalent to subprocess.run(..., check=True, stdout=PIPE).stdout, which means that subprocess.check_output(...) is getting your standard output by default, but your command is returning an exit code 1, which means error, so the command output will be captured by standard error, and I'm surprised that your e.stderr isn't working, but as a workaround you can capture the standard error in the standard output using stderr=subprocess.STDOUT, like this:

    subprocess.check_output(
        "ls non_existent_file; exit 0",
        stderr=subprocess.STDOUT,
        shell=True
    )
    

    Again, this comes from the Python docs referenced before.

    Update 1:

    To get e.stderr to work, you must use stderr=subprocess.PIPE, so the following should work:

    try:
        subprocess.check_output(
            ['clang', 'main.cpp', '-o', 'myprogram.exe'],
            stderr=subprocess.PIPE
        )
    except subprocess.CalledProcessError as e:
        print(e.stderr)
    

    Note that it is preferable to use a list to provide the command args (as stated in this comment).