web-dev-qa-db-ja.com

Fabricを使用してリモートシェルでrun()呼び出しを行うときにエラーコードをキャッチできますか?

通常、Fabricは、run()呼び出しがゼロ以外の終了コードを返すとすぐに終了します。ただし、一部のコールでは、これが予想されます。たとえば、PNGOutは、ファイルを圧縮できない場合、エラーコード2を返します。

現在、この制限を回避するには、シェルロジック(do_something_that_fails || trueまたはdo_something_that_fails || do_something_else)、しかし、私はむしろPython(Fabric Promiseがそうであるように))私のロジックを平易に保つことができます。

Fabricがパニックに陥って死ぬのではなく、エラーコードをチェックして対応する方法はありますか?私はまだ他の呼び出しのデフォルトの動作が欲しいので、環境を変更して動作を変更することは良い選択肢のように思えません(そして、私が覚えている限り、それを使用して、とにかく死ぬ代わりに警告するように伝えることができます)。

64
Alan Plum

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

更新:私の答えは時代遅れです。以下のコメントを参照してください。

90
akaihola

はい、できます。環境の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のドキュメントは here です。

29
ArtOfWarfare

どうやら環境をいじるis答え。

_fabric.api.settings_をコンテキストマネージャーとして(withとともに)使用して、個々のステートメントに適用できます。 run()local()、およびSudo()呼び出しの戻り値は、シェルコマンドの出力だけでなく、特別なプロパティ(_return_code_およびfailed)は、エラーへの対応を可能にします。

_subprocess.Popen_の動作やPythonの通常の例外処理に近いものを探していたと思います。

4
Alan Plum

これを試して

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
2
Yahya Yahyaoui