能否在远程shell中使用Fabric的run()调用捕获错误代码?

70 投票
4 回答
46870 浏览
提问于 2025-04-16 11:10

通常情况下,当运行的代码返回一个非零的退出代码时,Fabric会立刻停止。不过,有些情况下,这种行为是可以理解的。比如,PNGOut在无法压缩文件时会返回错误代码2。

目前,我只能通过一些命令行逻辑来绕过这个限制,比如使用do_something_that_fails || true或者do_something_that_fails || do_something_else,但我更希望能在普通的Python代码中保持我的逻辑(这也是Fabric所承诺的)。

有没有办法检查错误代码并对此做出反应,而不是让Fabric直接崩溃?我还是希望其他调用的默认行为保持不变,所以通过修改环境来改变它的行为似乎不是个好主意(而且据我记得,你只能用这种方式让它发出警告,而不是直接崩溃)。

4 个回答

4

看起来调整环境设置确实是解决问题的办法。

fabric.api.settings 可以作为上下文管理器使用,也就是说可以用 with 语句来应用它到特定的代码段。调用 run()local()sudo() 的返回值,不仅仅是你在命令行中执行的命令的输出,它们还有一些特别的属性,比如 return_codefailed,可以帮助你处理错误。

我想我其实是在寻找一种更接近 subprocess.Popen 或者 Python 通常的异常处理方式的东西。

29

是的,你可以这么做。只需要修改环境中的 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 的详细说明可以在 这里 找到。

97

你可以通过使用 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()

更新:我的回答已经过时了。请查看下面的评论。

撰写回答