17

SSH 接続のためにリモート サーバーをポーリングし、使用可能になったときに通知するために使用している Python プログラムが必要です。現在、paramiko を使用してこれを行っています。接続を試みます。失敗した場合は、成功するまで待機してから再試行するか、最大再試行します。これは機能しますが、少し扱いに​​くいです。また、paramiko は接続するかエラーをスローするように見えるので、これを行う唯一の方法は、悪い、悪い、悪い、try/except ブロックを使用することでした。メソッドは次のとおりです。

def check_ssh(self, ip, user, key_file, initial_wait=0, interval=0, retries=1):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    sleep(initial_wait)

    for x in range(retries):
        try:
            ssh.connect(ip, username=user, key_filename=key_file)
            return True
        except Exception, e:
            print e
            sleep(interval)
    return False

これよりもエレガントなソリューションが必要です。Paramiko は、私が選んだ SSH ライブラリですが、ここで提案を受け付けています。

明確にするために、コード実行の通常のフローを制御する手段として try / except を使用することは避けたいと思います。これは、不正なホスト キー、無効なユーザーなどの実際のエラーをキャッチするために使用する必要があります。

4

1 に答える 1

24

frb のコメントで述べたように、try ... exceptブロックは特定のサービスの可用性をテストするための優れたアプローチです。ただし、 「キャッチオール」exceptブロックを使用するべきではありませんが、サービスが利用できない場合に発生する特定の例外に限定してください。

ドキュメントによると、paramiko.SSHClient.connect接続中に発生した問題に応じて、さまざまな例外がスローされる場合があります。それらすべてをキャッチしたい場合、try ... exceptブロックは次のようになります。

try:
    ssh.connect(ip, username=user, key_filename=key_file)
    return True
except (BadHostKeyException, AuthenticationException, 
        SSHException, socket.error) as e:
    print e
    sleep(interval)

これらの例外のサブセットだけがあなたのケースに関連している場合は、それらのみを の後にタプルに入れますexcept

于 2013-01-09T14:05:32.960 に答える