Могу ли я улавливать коды ошибок при использовании вызовов Fabric для запуска() в удаленной оболочке?
Обычно Fabric завершает работу, как только вызов run() возвращает ненулевой код выхода. Однако для некоторых вызовов это ожидается. Например, PNGOut возвращает код ошибки 2, когда он не может сжать файл.
В настоящее время я могу обойти это ограничение только с помощью shell-логики (do_something_that_fails || true
или do_something_that_fails || do_something_else
), но я предпочел бы сохранить свою логику на простом Python (как и обещание Fabric).
Есть ли способ проверить код ошибки и отреагировать на него, а не наложить панику и умереть? Я по-прежнему хочу поведения по умолчанию для других вызовов, поэтому изменение его поведения путем изменения среды не похоже на хороший вариант (и, насколько я помню, вы можете использовать это только для того, чтобы предупредить его, а не умереть в любом случае).
Ответы
Ответ 1
Вы можете предотвратить прерывание при ненулевых кодах выхода с помощью диспетчера контекстов settings
и параметра warn_only
:
from fabric.api import settings
with settings(warn_only=True):
result = run('pngout old.png new.png')
if result.return_code == 0:
do something
elif result.return_code == 2:
do something else
else: #print error to user
print result
raise SystemExit()
Обновление: Мой ответ устарел. См. Комментарии ниже.
Ответ 2
Да, вы можете. Просто измените среду abort_exception
. Например:
from fabric.api import settings
class FabricException(Exception):
pass
with settings(abort_exception = FabricException):
try:
run(<something that might fail>)
except FabricException:
<handle the exception>
Документация на abort_exception
здесь.
Ответ 3
По-видимому, беспорядок в среде - это ответ.
fabric.api.settings
может использоваться как менеджер контекста (с with
), чтобы применить его к отдельным операторам. Возвращаемое значение вызовов run()
, local()
и sudo()
является не только результатом команды оболочки, но также имеет специальные свойства (return_code
и failed
), которые позволяют реагировать на ошибки.
Я предполагаю, что я искал что-то более близкое к поведению subprocess.Popen
или обычной обработки исключений Python.
Ответ 4
попробуйте это
from fabric.api import run, env
env.warn_only = True # if you want to ignore exceptions and handle them yurself
command = "your command"
x = run(command, capture=True) # run or local or sudo
if(x.stderr != ""):
error = "On %s: %s" %(command, x.stderr)
print error
print x.return_code # which may be 1 or 2
# do what you want or
raise Exception(error) #optional
else:
print "the output of %s is: %s" %(command, x)
print x.return_code # which is 0