2013-01-09 10 views
11

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

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ライブラリですが、ここには何の示唆もありません。明確にするために

、私はコード実行の通常の流れを制御する手段として除いて試して/使用しないようにしたい - それは、そのような悪いホストキーなど、実際のエラーをキャッチするために使用されるべきで、無効なユーザーなど

+7

「これを行うために私が見ることができる唯一の方法は、悪い、悪い、悪い」try/exceptブロックであったのです。なぜそれは悪いですか? –

+9

あなたは間違いなく「例外」を捕まえることが悪いことは間違いありません。しかし、paramikoによって投げられた特定の例外をキャッチすることはまったく悪くありません。 –

+0

実際、プログラムフローの手段として例外処理を使用すると、一般的に悪くなります。http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Exceptions – nightowl

答えて

12

として、 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後のタプルにのみを入れました。

+0

一般的な例外だけを指定している私の緩やかなコードのフェアポイント: try/catch私は悪いホストキーのようなものは、実際のエラーではないと推測します。 "サーバはまだ起動していません" - 私はtry/exceptブロックが待機ループを制御することを望んでいません。コードの)。 – nightowl

関連する問題