17

我需要一个 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

一定有比这更优雅的解决方案。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)

如果这些异常中只有一部分与您的情况相关,则仅将这些异常放入元组 after except

于 2013-01-09T14:05:32.960 回答