Сохранить сообщение об ошибке команды subprocess
при выполнении команды bash с помощью подпроцесса я могу столкнуться с ситуацией, когда команда недопустима. В этом случае bash вернет ошибку messsage. Как мы можем поймать это сообщение? Я хотел бы сохранить это сообщение в файл журнала. Ниже приведен пример, где я пытаюсь перечислить файлы в несуществующем каталоге.
try:
subprocess.check_call(["ls", "/home/non"])
df = subprocess.Popen(["ls", "/home/non"], stdout=subprocess.PIPE)
output, err = df.communicate()
# process outputs
except Exception as error:
print error
sys.exit(1)
Bash будет печатать "ls: не может получить доступ /home/non: нет такого файла или каталога". Как я могу получить это сообщение об ошибке? Ошибка, пойманная исключением строка явно отличается, в ней говорится: "Command '['ls', '/home/non']' возвращено ненулевое состояние выхода 2".
2 ответов
вы можете перенаправить stderr в файловый объект:
from subprocess import PIPE, CalledProcessError, check_call, Popen
with 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)
вывод в лог.txt:
ls: cannot access /home/non: No such file or directory
если вы хотите, чтобы сообщение в 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)
для python 2.6 e.message
не работает. Вы можете использовать аналогичную версию python 2.7 check_output
это будет работать с python 2.6:
from subprocess import PIPE, CalledProcessError, Popen
def 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 out
try:
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)
"ls: не удается получить доступ / home / non: нет такого файла или каталога" созданный , не bash
здесь.
если вы хотите обрабатывать несуществующие файлы с помощью обработки исключений, используйте subprocess.check_output()
:
#!/usr/bin/env python
from subprocess import check_output, STDOUT, CalledProcessError
try:
output = check_output(['ls', 'nonexistent'], stderr=STDOUT)
except CalledProcessError as exc:
print(exc.output)
else:
assert 0
выход
ls: cannot access nonexistent: No such file or directory