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)