如何直接从Python捕获异常和输出运行Fabric任务?

时间:2015-12-30 01:38:13

标签: python fabric

我想在没有直接来自Python的cli的情况下运行我现有的fabfile任务。 我如何抓住'执行'异常并在发生任何异常时捕获输出以进行记录?

@roles(['localhost'])
def my_sudo_task():
    sudo('ls -l /root/')

from fabfile import my_sudo_task
from fabric.tasks import execute

execute(my_sudo_task)

这是我的确切问题:

try:
    # is there a way to leave out stderr and capture it somehow?
    with settings(hide('stdout', 'stderr', 'aborts', 'warnings', 'running')):
        execute(my_sudo_task)
except Exception as e:  # doesnt catch error
    print ('ERROR')
    raise
except:
    print ('ERROR')  # catches but lacks the error message that i can log

3 个答案:

答案 0 :(得分:1)

您应该通过检查任务中的结果代码来处理错误。例外情况不够具有描述性。

from fabric.api import *

@roles(['localhost'])
def my_sudo_task():
    with settings(warn_only=True):
        result = sudo('ls -l /root/')

    if result.return_code == 0:
        [do something...]
    elif result.return_code == 1:
        [do something...]
    else:
        [do something else...]



from fabfile import my_sudo_task
from fabric.tasks import execute

execute(my_sudo_task)

请参阅failure handling上的教程部分。

答案 1 :(得分:0)

以下解决了我的问题

try:
    with settings(hide('stdout', 'stderr', 'aborts', 'warnings', 'running')):
        execute(my_sudo_task)
except SystemExit as e:
    print (e.message)

因为'执行'在技​​术上不会抛出异常

issubclass(SystemExit, Exception) = False

答案 2 :(得分:0)

在fabric.exceptions模块中定义了NetworkError和CommandTimeout异常。 execute()调用返回一个字典,其中包含由主机名作为键执行的任务返回的任何内容。如果遇到异常,它也将存储在字典中。您可以检查异常的'message'属性以获取问题的字符串描述。请参阅以下示例:

>>> from fabric.api import run, execute
>>> from fabric.context_managers import quiet
>>> from fabric.state import env
>>> env.skip_bad_hosts = True
>>> env.warn_only = True
>>> def task_a():
...  return run('pwd')
...
>>> with quiet():
...  a = execute(task_a,hosts=['badhost'])
...
>>> a
{'badhost': NetworkError(Name lookup failed for badhost) => gaierror(8, 'nodename nor servname provided, or not known')}
>>> type(a['badhost'])
<class 'fabric.exceptions.NetworkError'>
>>> a['badhost'].message
'Name lookup failed for badhost'