使用Expect脚本处理路由器/交换机带颜色文本的登录问题
解决Expect脚本因ANSI颜色代码无法登录带彩色输出的路由器问题
我之前也碰到过一模一样的困扰!当远程路由器返回带ANSI颜色控制码的输出时,Expect的文本匹配逻辑会被这些额外的控制字符打乱——毕竟它默认是按纯文本内容匹配的,而手动登录时终端会自动解析这些颜色代码并显示彩色文本,所以不会影响认证流程。
下面分享几个实用的解决方法:
1. 在Expect脚本中主动过滤ANSI颜色代码
这是最通用的方案,不管设备是否支持关闭颜色,都能生效。我们可以写一个小函数,把输出中的ANSI颜色控制码(格式通常是\x1B[0-9;]*m)全部替换为空字符串,再用清理后的内容进行匹配。
示例脚本:
# 定义过滤ANSI颜色代码的函数 proc strip_ansi_codes {input} { return [regsub -all {\x1B\[[0-9;]*m} $input ""] } # 启动SSH连接 spawn ssh your_username@router_ip expect { -re {.*} { # 清理当前收到的输出内容 set cleaned_buffer [strip_ansi_codes $expect_out(buffer)] # 检查清理后的内容是否包含密码提示符 if {[string match "*password:*" $cleaned_buffer]} { send "your_password\r" # 后续匹配命令行提示符时也可以用同样的过滤方式 expect -re {.*} { set cleaned_prompt [strip_ansi_codes $expect_out(buffer)] if {[string match "*router#*" $cleaned_prompt]} { puts "登录成功!" send "show running-config\r" } } } } }
2. 直接关闭路由器的彩色输出
如果有权限修改路由器配置,这是最省心的办法。大部分网络设备都支持关闭终端彩色输出的命令:
- 临时生效(当前会话):登录后执行
terminal no color或者no terminal color(不同设备命令可能略有差异) - 永久生效:进入全局配置模式,添加
line vty 0 4(根据你的VTY线路范围调整),然后配置no exec prompt timestamp或者no terminal color保存配置。
3. 调整Expect的匹配规则,兼容颜色代码
如果不想过滤代码,也可以修改匹配的正则表达式,把可能出现的颜色代码包含进去。比如原来的expect "Password:"可以改成:
expect -re {\x1B\[[0-9;]*mPassword:\x1B\[[0-9;]*m}
不过这种方式局限性较大——不同设备的颜色代码可能不同,而且提示符前后的颜色控制码也可能变化,不如过滤代码的方法通用。
调试小技巧
可以在脚本开头添加 exp_internal 1,开启Expect的调试模式,这样就能看到脚本实际接收到的原始输出内容,确认是不是ANSI颜色代码在干扰匹配。
试试上面的方法,我当时用第一个过滤代码的方案就顺利解决了问题,你可以先调试看看设备返回的原始输出,再针对性调整脚本~
内容的提问来源于stack exchange,提问作者Umi
相关产品推荐
相关产品推荐

