自定义TextFSM模板解析Cisco IOS MAC地址表报错排查
问题根因
报错和正则基础匹配能力无关,是TextFSM模板规则未覆盖真实回显场景、状态机逻辑缺失导致的,核心原因有3个:
- 数据行正则未兼容行尾空格:你写的TYPE2数据行匹配规则在
${PORT}后直接绑定行尾符$$,但设备实际回显的每条数据行末尾都带有大量尾随空格,PORT字段匹配完成后剩余的空格无法被正则覆盖,导致数据行匹配失败,直接触发^. -> Error规则抛出异常,这是当前报错的直接诱因。 - 未覆盖分页标记场景:回显末尾存在
--More--分页字符,TYPE2状态下没有配置对应匹配规则,就算修复了数据行匹配,解析到分页行时依然会触发Error。 - 正则测试场景不全:在regex101测试时仅验证了去除首尾空格的单行样本,没有覆盖带尾随空格的真实数据行、分页符、表头前后的杂项行,也没有考虑TextFSM的逐行状态匹配机制——只要某一非空行在当前状态下没有被任何非Error规则命中,就会直接抛异常。
修复方案
1. 修改TextFSM模板
调整后的完整模板如下,核心修正了行尾匹配、分页兼容、杂项行兜底逻辑:
Value VLAN (\S+) Value MAC ([0-9a-fA-F]{4}\.[0-9a-fA-F]{4}\.[0-9a-fA-F]{4}) Value TYPE (\S+) Value PORT (\S+) Start ^Vlan\s+Mac\s+Address\s+Type\s+Ports -> TYPE1 ^\s*vlan\s+mac address\s+type\s+protocols\s+port -> TYPE2 ^.* -> Continue TYPE1 ^\s*Mac\sAddress\sTable ^-+ ^\s*$$ ^Vlan\s+Mac Address\s+Type\s+Ports ^-+\s+-+\s+-+\s+-+\s*$$ ^\s*${VLAN}\s+${MAC}\s+${TYPE}\s+${PORT}\s*$$ -> Record ^Total\s+Mac\s+Addresses\s+for\s+this\s+criterion\:\s+\d+ -> End ^\s*--More--.* -> Continue ^. -> Error TYPE2 ^Unicast\sEntries ^\s+vlan\s+mac address\s+type\s+protocols\s+port ^-+\+-+\+-+\+-+\+-+.* ^\s*${VLAN}\s+${MAC}\s+${TYPE}\s+\S+\s+${PORT}\s*$$ -> Record ^\s*$$ -> End ^\s*--More--.* -> Continue ^. -> Error
具体修改点:
- 将PORT字段的匹配规则从
([^,\s]+)调整为(\S+),适配端口字段的通用匹配逻辑,避免特殊场景下匹配异常 - 所有涉及行尾匹配的正则(分隔线、数据行),在
$$前增加\s*,兼容行尾任意数量的尾随空格 - 在TYPE1、TYPE2状态下增加
^\s*--More--.* -> Continue规则,匹配分页标记行,直接消费该行不做处理,继续解析后续内容 - 在Start状态增加
^.* -> Continue通用兜底规则,忽略所有未匹配到表头跳转规则的杂项行(比如残留的设备提示符、命令行、Unicast Entries提示行等),避免异常跳转
2. 优化Netmiko调用逻辑
建议连接设备后提前关闭分页,从源头避免--More--字符出现在回显中,同时增加超时时间适配长MAC地址表场景:
from netmiko import ConnectHandler import Seeker.helpers.constants root = Seeker.helpers.constants.get_project_root() show_mac_template = f'{root}/ntc_textfsm_templates/cisco_ios_show_mac_address-table.textfsm' device = { 'host': 'r1.nunya.com', 'device_type': 'cisco_ios', 'username': 'cisco', 'password': 'password', 'secret': 'secret', } ssh = ConnectHandler(**device) ssh.enable() # 提前关闭分页,避免--More--标记 ssh.send_command("terminal length 0") show_mac = ssh.send_command( "show mac address-table dynamic", use_textfsm=True, textfsm_template=show_mac_template, read_timeout=60 ) ssh.disconnect()
内容的提问来源于stack exchange,提问作者Ryan Bell
相关产品推荐
相关产品推荐

