You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义TextFSM模板解析Cisco IOS MAC地址表报错排查

问题根因

报错和正则基础匹配能力无关,是TextFSM模板规则未覆盖真实回显场景、状态机逻辑缺失导致的,核心原因有3个:

  1. 数据行正则未兼容行尾空格:你写的TYPE2数据行匹配规则在${PORT}后直接绑定行尾符$$,但设备实际回显的每条数据行末尾都带有大量尾随空格,PORT字段匹配完成后剩余的空格无法被正则覆盖,导致数据行匹配失败,直接触发^. -> Error规则抛出异常,这是当前报错的直接诱因。
  2. 未覆盖分页标记场景:回显末尾存在 --More--分页字符,TYPE2状态下没有配置对应匹配规则,就算修复了数据行匹配,解析到分页行时依然会触发Error。
  3. 正则测试场景不全:在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:57:27