Can I catch error codes when using Fabric to run() calls in a remote shell?

前端 未结 4 622
花落未央
花落未央 2020-12-23 13:17

Normally Fabric quits as soon as a run() call returns a non-zero exit code. For some calls, however, this is expected. For example, PNGOut returns an error code of 2 when it

相关标签:
4条回答
  • 2020-12-23 13:36

    Yes, you can. Just change the environment's abort_exception. For example:

    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>
    

    The documentation on abort_exception is here.

    0 讨论(0)
  • 2020-12-23 13:44

    try this

    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
    
    0 讨论(0)
  • 2020-12-23 13:50

    Apparently messing with the environment is the answer.

    fabric.api.settings can be used as a context manager (with with) to apply it to individual statements. The return value of run(), local() and sudo() calls isn't just the output of the shell command, but also has special properties (return_code and failed) that allow reacting to the errors.

    I guess I was looking for something closer to the behaviour of subprocess.Popen or Python's usual exception handling.

    0 讨论(0)
  • 2020-12-23 13:54

    You can prevent aborting on non-zero exit codes by using the settings context manager and the warn_only setting:

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

    Update: My answer is outdated. See comments below.

    0 讨论(0)
提交回复
热议问题