Save error message of subprocess command Save error message of subprocess command bash bash

Save error message of subprocess command


"ls: cannot access /home/non: No such file or directory" is generated by ls command, not bash here.

If you want to handle non-existing files using exception handling then use subprocess.check_output():

#!/usr/bin/env pythonfrom subprocess import check_output, STDOUT, CalledProcessErrortry:    output = check_output(['ls', 'nonexistent'], stderr=STDOUT)except CalledProcessError as exc:    print(exc.output)else:    assert 0

Output

ls: cannot access nonexistent: No such file or directory


You can redirect stderr to a file object:

from subprocess import PIPE, CalledProcessError, check_call, Popenwith open("log.txt", "w") as f:    try:        check_call(["ls", "/home/non"], stderr=f)        df = Popen(["ls", "/home/non"], stdout=PIPE)        output, err = df.communicate()    except CalledProcessError as e:        print(e)        exit(1)

Output to log.txt:

ls: cannot access /home/non: No such file or directory

If you want the message in the except:

try:    check_call(["ls", "/home/non"])    df = Popen(["ls", "/home/non"], stdout=PIPE)    output, err = df.communicate()except CalledProcessError as e:    print(e.message)

For python 2.6 the e.message won't work. You can use a similar version of python 2.7's check_output that will work with python 2.6:

from subprocess import PIPE, CalledProcessError, Popendef check_output(*args, **kwargs):    process = Popen(stdout=PIPE, *args, **kwargs)    out, err = process.communicate()    ret = process.poll()    if ret:        cmd = kwargs.get("args")        if cmd is None:            cmd = args[0]        error = CalledProcessError(ret, cmd)        error.out = out        error.message = err        raise error    return outtry:    out = check_output(["ls", "/home"], stderr=PIPE)    df = Popen(["ls", "/home/non"], stdout=PIPE)    output, err = df.communicate()except CalledProcessError as e:    print(e.message)else:    print(out)