Python 在远程shell中使用Fabric运行()调用时,是否可以捕获错误代码?

Python 在远程shell中使用Fabric运行()调用时,是否可以捕获错误代码?,python,error-handling,fabric,Python,Error Handling,Fabric,通常,只要run()调用返回非零退出代码,Fabric就会退出。然而,对于一些电话来说,这是意料之中的。例如,PNGOut无法压缩文件时返回错误代码2 目前,我只能通过使用shell逻辑(do_something_fails | | | true或do_something_fails | | | do_something _other)来规避这一限制,但我更希望能够用简单的Python保存我的逻辑(这是Fabric的承诺) 有没有一种方法可以检查错误代码并对其作出反应,而不是让织物死机?我仍然需

通常,只要run()调用返回非零退出代码,Fabric就会退出。然而,对于一些电话来说,这是意料之中的。例如,PNGOut无法压缩文件时返回错误代码2

目前,我只能通过使用shell逻辑(
do_something_fails | | | true
do_something_fails | | | do_something _other
)来规避这一限制,但我更希望能够用简单的Python保存我的逻辑(这是Fabric的承诺)


有没有一种方法可以检查错误代码并对其作出反应,而不是让织物死机?我仍然需要其他调用的默认行为,因此通过修改环境来更改其行为似乎不是一个好的选择(据我回忆,您只能用它来告诉它警告,而不是死掉)。

显然,搞乱环境就是答案

fabric.api.settings
可用作上下文管理器(使用
with
)将其应用于单个语句。
run()
local()
sudo()
调用的返回值不仅是shell命令的输出,还具有允许对错误做出反应的特殊属性(
return\u code
failed


我想我在寻找更接近
subprocess.Popen的行为或Python通常的异常处理的东西。

您可以通过使用
设置
上下文管理器和
仅警告
设置来防止非零退出代码中止:

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()

更新:我的答案过时了。见下面的评论

是的,你可以。只需更改环境的
异常中止
。例如:

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>
来自fabric.api导入设置
类FabriceException(异常):
通过
使用设置(异常中止=FabriceException):
尝试:
运行()
除FabriceException外:
关于异常中止的文档是。

试试这个

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

在有人将其标记为重复之前:,但正如我所说,我希望对错误做出反应,而不是忽略它们。目前接受的答案是日期。自2013年7月以来,有一个环境变量允许您指定发生错误时应引发的异常(默认为
SystemExit
,它不是异常的后代,这就是它通常导致程序崩溃的原因)。请参阅我的答案://,我很好奇Invoke将如何处理此问题。您甚至不需要检查返回代码,result的值根据任务的成功状态计算为布尔值true或false。这对超时错误不起作用。无论是否使用“With settings”,甚至使用try/except,结构仍然完全退出。-1:此答案已注明日期-自2013年7月以来,可以指定在调用错误时调用哪个异常。在这里可以看到我的答案:我修复了Python缩进,但是现在我无法删除为应用编辑而添加的额外文本。您也可以使用
result.successed
result.failed
。请注意不要直接计算
bool(result)
,因为它使用输出,因此与
hide(“warnings”)
和类似工具结合使用时,将无法区分成功与失败。不过,这似乎不能提供对命令退出代码的访问。@AlanPlum-您可以获得异常消息。。。但是你是对的,我看不到获取退出代码的方法。我尝试了上述方法,结果如下:
TypeError:run()在Fabric 1.10.2和Paramiko 1.15.2中获得了一个意外的关键字参数“capture”
capture=True
仅适用于
local(command,capture=True)