优雅的方式来测试SSH可用性

nig*_*owl 15 python ssh paramiko

我需要一个Python程序,我用它来轮询远程服务器以获得SSH连接,并在它可用时通知.我目前正在使用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
Run Code Online (Sandbox Code Playgroud)

必须有比这更优雅的解决方案.Paramiko是我选择的SSH库,但我愿意接受任何建议.

为了澄清,我想避免使用try/except作为控制正常代码执行流程的手段 - 它应该用于捕获实际错误,例如错误的主机密钥,无效的用户等.

sil*_*ado 20

正如frb的评论中所提到的,try ... except块是测试特定服务可用性的好方法.您不应该使用"catch-all" 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)
Run Code Online (Sandbox Code Playgroud)

如果只是这些异常的一部分与您的案例相关,那么只将那些异常放入元组中except.