Netmiko配置备份:如何忽略认证/超时等异常并完成设备遍历
使用Netmiko批量备份设备时,遇到认证/连接异常如何让脚本继续执行?
这是我首次在Stack Overflow提问,之前靠这个平台快速入门了脚本开发,但现在碰到个棘手问题:用Netmiko批量备份设备配置时,只要遇到认证失败、连接超时、连接拒绝这类异常,脚本就直接中断,没法遍历完所有设备。我需要修改代码,让脚本忽略这些异常,继续处理后续设备的备份。
我的代码
# SSH to Multiple Devices from devices file import csv import logging from netmiko import ConnectHandler from netmiko import ConnLogOnly from getpass import getpass import paramiko.ssh_exception import netmiko.exceptions from netmiko.exceptions import NetMikoTimeoutException from netmiko.exceptions import NetMikoAuthenticationException from paramiko.ssh_exception import AuthenticationException log_level = logging.INFO log_file = "backup_script.log" host_list = input('Enter /path/to/filename of CSV file: ') uname = input('Enter username: ') passwd = getpass() with open(host_list, mode='r') as file: reader = csv.DictReader(file) devices = [row for row in reader] for device in devices: try: connection = ConnectHandler( device_type=device['device_type'], host=device['hostname'], username=(uname), password=(passwd) ) except NetMikoTimeoutException: print("Connection timed out, trying again...") except NetMikoAuthenticationException: print("Authentication failed, please check credentials.") except Exception as e: print(f"An unexpected error occurred: {str(e)}") connection = ConnectHandler( device_type=device['device_type'], host=device['hostname'], username=(uname), password=(passwd) ) filename = (f"backup_testing/{device['hostname']}-running-config") connection.send_command('term len 0') showrun = connection.send_command('show run') log_file1 = open(filename, "a") # in append mode log_file1.write(showrun) log_file1.write(showrun) log_file1.write("\n") connection.disconnect() print(f"{device['hostname']} Done!")
执行报错输出
python3.11 backup-multiple-routers-csv-input-file-with-logging.py Enter /path/to/filename of CSV file: test_backup_list.csv Enter username: adm_teagumi1 Password: Authentication failed, please check credentials. Traceback (most recent call last): File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/netmiko/base_connection.py", line 1142, in establish_connection self.remote_conn_pre.connect(**ssh_connect_params) File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/paramiko/client.py", line 485, in connect self._auth( File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/paramiko/client.py", line 818, in _auth raise saved_exception File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/paramiko/client.py", line 805, in _auth self._transport.auth_password(username, password) File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/paramiko/transport.py", line 1638, in auth_password return self.auth_handler.wait_for_response(my_event) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/paramiko/auth_handler.py", line 263, in wait_for_response raise e paramiko.ssh_exception.AuthenticationException: Authentication failed. During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/adm_teagumi1/backup-multiple-routers-csv-input-file-with-logging.py", line 36, in <module> connection = ConnectHandler( ^^^^^^^^^^^^^^^ File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/netmiko/ssh_dispatcher.py", line 410, in ConnectHandler return ConnectionClass(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/netmiko/base_connection.py", line 493, in __init__ self._open() File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/netmiko/base_connection.py", line 498, in _open self.establish_connection() File "/home/adm_teagumi1/.local/lib/python3.11/site-packages/netmiko/base_connection.py", line 1179, in establish_connection raise NetmikoAuthenticationException(msg) netmiko.exceptions.NetMikoAuthenticationException: Authentication to device failed.
问题常见原因
- 用户名或密码无效
- SSH密钥文件错误
- 连接到错误的设备
设备配置:cisco_ios USFW-NDC-LAB-MGMT-A02:22,认证失败。
解决方案
你的代码核心问题是异常处理范围太小,而且在捕获异常后又重复调用了ConnectHandler,导致异常再次抛出中断脚本。正确的做法是把当前设备的所有操作(连接、备份、断开)都放到try块里,捕获异常后直接跳过当前设备,继续处理下一个。
修改后的代码如下:
# SSH to Multiple Devices from devices file import csv import logging from netmiko import ConnectHandler from getpass import getpass from netmiko.exceptions import NetMikoTimeoutException, NetMikoAuthenticationException # 初始化日志 logging.basicConfig( filename="backup_script.log", level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" ) host_list = input('输入CSV文件路径: ') uname = input('输入用户名: ') passwd = getpass() with open(host_list, mode='r') as file: reader = csv.DictReader(file) devices = list(reader) for device in devices: hostname = device['hostname'] try: # 建立连接 connection = ConnectHandler( device_type=device['device_type'], host=hostname, username=uname, password=passwd ) logging.info(f"成功连接到 {hostname}") # 获取配置 connection.send_command('term len 0') showrun = connection.send_command('show run') # 保存配置(用with自动关闭文件) filename = f"backup_testing/{hostname}-running-config" with open(filename, "w") as log_file1: # 用w模式覆盖旧备份,a是追加可根据需求调整 log_file1.write(showrun) log_file1.write("\n") # 断开连接 connection.disconnect() print(f"{hostname} 备份完成!") logging.info(f"{hostname} 备份已保存") except NetMikoTimeoutException: error_msg = f"{hostname} 连接超时" print(error_msg) logging.error(error_msg) continue # 跳过当前设备,继续下一个 except NetMikoAuthenticationException: error_msg = f"{hostname} 认证失败,请检查凭据" print(error_msg) logging.error(error_msg) continue except Exception as e: error_msg = f"{hostname} 发生意外错误: {str(e)}" print(error_msg) logging.error(error_msg) continue
关键改动说明
- 扩大try块范围:把连接、备份、断开操作都放到try里,确保任何步骤出错都能被捕获
- 移除重复的ConnectHandler调用:原来的代码在捕获异常后又重新调用一次,直接导致异常再次抛出
- 添加continue语句:捕获异常后跳过当前设备,继续遍历下一个
- 优化文件操作:用
with open自动管理文件,避免忘记关闭 - 完善日志记录:把错误信息同时记录到日志文件,方便后续排查
- 简化导入:去掉没用的导入语句,让代码更简洁
内容的提问来源于stack exchange,提问作者olddude
相关产品推荐
相关产品推荐

