简单示例中的Cisco IOS的​​Tcl

想象一下,您需要从头开始部署许多相同类型的Cisco接入交换机。 典型的配置包括主机名和域,默认网关,密码,用户列表,SVI的IP地址,VLAN编号,上行链路干线的设置等。 每次用手输入它都非常漫长且无济于事。 当然,您可以创建一个典型的配置并通过(T)FTP上传它,但是,首先,它至少需要从控制台进行最少的配置,其次,仍然必须更改可变的配置参数。 为了解决这些(以及许多其他)任务,Cisco IOS包含一个功能强大的自动化工具-内置Tcl解释器(带有Tcl的Cisco IOS脚本)。

什么是Tcl


Tcl(可读的“ tickle”,有时是“ flowed”)是80年代后期开发的一种解释性编程语言,用于嵌入控制台应用程序。 现代Tcl的功能范围非常广泛:这里支持OOP,以及高级的正则表达式工具,动态数组等。

对这种语言的支持首次出现在Cisco IOS 12.2(3)T平台上(在某些来源中以12.3(2)表示,但我没有对此进行确认),目前有几种选择:

  • 具有命令行界面的Tcl解释器。 它已集成到Cisco IOS平台的各种版本中,包括IOS XE和XR,并且可用于各种设备。 允许您执行Tcl命令,将现成的脚本作为文件运行,等等。 不使用iOS作为操作系统但例如Cat OS或ASA(在同名防火墙中)的设备不包含解释器命令行。
  • T.N. “内置事件管理器”或EEM-事件跟踪系统,可让您自动实时对其进行响应。 例如,使用电子邮件通知监视远程主机。 EEM脚本(小程序)用Tcl编写,但是EEM本身不提供单独的Tcl命令行。 使用示例请参见此处 。 从9.2(1)版及更高版本开始,在Nexus(NX OS)和ASA平台上都可以使用EEM。
  • 语音菜单系统IVR(交互式语音响应)。

如何确定知道设备型号或iOS版本的命令解释器的存在? 为此有一个Cisco Feature Navigator

图片

研究功能”菜单项允许您为给定的IOS培训版本或特定的硬件平台选择特定的IOS版本。 “ 研究软件”菜单项使您可以查找具有给定硬件的Tcl支持的所有iOS版本。 我们单击,按名称(功能名称)“带有Tcl的Cisco IOS脚本”(或简称为“ Tcl”)过滤“筛选依据”字段,将功能名称添加到列表中,选择“ Train release”,并获得包含此功能的所有IOS版本的列表:



不幸的是,CFN数据库不完整,有时无法显示所有信息。 因此,对于CAT2960S平台,导航器在IOS 15.2E1版本中显示了Tcl的存在,而在15.2E9版本中却没有显示,尽管实际上Tcl解释器无处不在。

使用Tcl在Cisco IOS中可以做什么? 相当多:浏览和更改配置,创建交互式脚本,对MIB对象,TCP和UDP套接字进行操作,甚至... 编写整个Web Shell!

通常,Tcl程序包含一系列用换行符或分号分隔的命令。 非说明性示例:

puts "Hello, world!"; puts "My first Tcl IOS script!" 

一些运营商:

#注释到行尾
set a 1分配a = 1
$a获取变量的值
{ }块语句-定义循环或条件的主体
[ ]替换运算符-执行时,将替换方括号中包含的表达式的计算值,而不是方括号
== <= <>比较运算符
puts "text"在标准输出中显示字符串“文本”(即到控制台)
puts $a的价值类似地puts $a
gets stdin从控制台读取值
set a [gets stdin]从控制台输入一个值并为其分配变量a
for {set i 1} {$i < 10} {inrc i} {....} for循环
proc {argument, ....} {body}过程

有关更完整的列表,请参阅progopedia.ru/language/tcl

Tcl解释器由特权执行模式下的tclsh命令启动:

 sw#Tclsh sw(tcl)# 

运行第一个脚本:

图片

退出解释器是tclquit命令或只是退出。 Tcl区分大小写,因此Puts "Hello, world"将引发错误,但是IOS shell的shell寄存器并不重要。 如果输入命令是可执行的,则首先由Tcl解释器处理所有输入命令。 Tcl,它执行并将结果输出到TTY设备。 如果命令不能由解释器执行,则将其传递给IOS命令解析器。 因此,一个脚本可以将Tcl语句和IOS命令结合在一起。 IOS环境不包含完整的文本编辑器,因此必须通过外部方式创建预定义的脚本,然后才将其复制到闪存或内存中。 它还支持在随后启动时以字节码预编译脚本。 脚本文件的启动由命令执行

 tclsh flash:filename 

允许来自不同TTY会话的多个Tcl解释器会话。

Tcl解释器内部命令:
exec-从IOS CLI特权EXEC集执行带引号的命令。
sw(tcl)#exec "show int fa0"sw(tcl)#exec "show int fa0"

图片

ios-config-从全局配置模式执行命令。 在其后面,用单独的对引号表示所有后续子配置命令。 例如:
sw(tcl)#ios_config "int fa0" "ip address 192.168.0.1 255.255.255.0" "no shut"
等效于一系列iOS命令:

 sw#conf te sw(config)#int fa0 sw(conf-int)#ip address 192.168.0.1 255.255.255.0 sw(conf-int)#no shut 

Tcl解释器可防止exec进程直接与控制台进行交互。 因此,使用typeahead命令将数据传输到从Tcl Shell启动的exec进程中:
typeahead "y\ny"
exec "reload"

首先,两个“ y”字符将存储在输入缓冲区中,并用换行符(\ n)分隔,然后将启动reload exec命令,该命令将从输入缓冲区中读取cancel或Confirm Reset命令,并(如果需要)保存配置。

挠痒痒不支持键入,在使用变量进行操作时必须记住这一点:

图片

嵌套运算符[expr {..}]计算大括号($ a + $ b)中指定的表达式的值,并执行此值的替换而不是方括号。

Tcl中的示例过程:
proc ping_net {x} {
for {set n 1} {$n < $x} {incr n} {
exec "ping 192.168.0.$n"
}
}

当您输入大括号时,解释器将不会关闭命令行,直到您输入一对大括号为止。 该过程存储在解释器内存中,直到使用tclquit命令结束解释器会话为止。 这样就可以启动过程并访问以前启动的脚本的变量。 请记住,脚本中的错误可能导致循环和阻塞您的(V)TTY会话! 控制台没有紧急关闭功能(例如Ctrl + Break),唯一的方法是启动新会话并使用clear line命令clear line “冻结”会话。

现在让我们继续解决一个实际问题。 开箱即用的是48端口Cat2950S。 下面的脚本

  • 从控制台请求开关sw_num的序列号
  • 设置其主机名,格式为switch_ <sw_num>
  • 请求和设置特权EXEC控制台的密码
  • 根据输入的交换机号在其Fa0控制接口(192.168.0.x)和Vlan1接口(10.0.x.254)上配置地址
  • 创建一个基于端口的DHCP保留和一个48个地址的池,其中为每个客户端保留一个IP地址,该地址的低八位位组等于该客户端通过其连接的端口的序列号。

 puts "Enter Switch number:" set sw_num [gets stdin] ios_config "hostname switch_$sw_num" puts "Enter password (secret):" set pass [gets stdin] ios_config "enable secret 0 $pass" ios_config "line 0 16" "password 0 $pass" "login" ios_config "int fa0" "ip address 192.168.0.$sw_num 255.255.255.0" "no shut" ios_config "int vlan1" "ip address 10.0.$sw_num.254 255.0.0.0" "no shut" ios_config "ip dhcp use subscriber-id client-id" ios_config "ip dhcp subscriber-id interface-name" #    48       subscriber-id for {set i 1} {$i <= 48} {incr i} {ios_config "int Gi1/0/$i" "ip dhcp server use subscriber-id client-id"} ios_config "ip dhcp pool POOL1" "network 10.0.0.0 255.0.0.0" "reserved-only" "default-router 10.10.0.254" #    48  IP-,   .  for {set i 1} {$i <= 48} {incr i} {ios_config "ip dhcp pool POOL1" "address 10.0.$sw_num.$i client-id Gi1/0/$i ascii"} # 

注意1.此脚本中有一个小逻辑错误。 尝试找到她。

注意2.一些文本编辑器喜欢在文件末尾放置一个不可打印的EoF字符。 在IOS控制台中,可以通过列出cat或更多的文件内容来看到它。 偶然发现EoF之后,Tcl解释器将抛出错误并忽略整行。 因此,我在脚本末尾留下了转义的注释标记。

问题出现了:如何通过未配置IP的脚本(仅通过控制台端口工作)如何将脚本写入到交换机的内存中? 请勿手动输入脚本! 是否可以手动配置管理界面并每次使用FTP? 不,它可以更容易。 Cisco IOS可以使用Xmodem协议通过控制台串行端口直接复制文件,并将其保存到闪存中。 为此,您需要具有Xmodem支持的终端仿真器,例如ZOC或Tera Term(但是流行的免费Putty ,,,将无法工作!)。 复制是通过IOS 复制xmodem:flash:filename命令执行的,之后您需要在终端仿真器菜单中执行File Transfer:

图片

这也可以在ROMmon中完成(例如,如果您“拆除”了没有特权EXEC密码的交换机配置)。 但是不支持将文件复制回(从交换机的闪存到PC)。

不幸的是,您无法从Tcl打开到远程路由器的telnet会话。 尝试时
sw(tclsh)#exec "telnet host"会话将仅在密码输入阶段冻结。

这简要介绍了Tcl语言在Cisco IOS平台上的功能;您可以在Cisco网站上的《带有TCL配置指南的Cisco IOS脚本》文档中更详细地研究该问题。

Source: https://habr.com/ru/post/zh-CN455401/


All Articles