TCL脚本实例解读.doc_第1页
TCL脚本实例解读.doc_第2页
TCL脚本实例解读.doc_第3页
TCL脚本实例解读.doc_第4页
TCL脚本实例解读.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

TCL脚本实例解读作者:杨帆、老卢前言Sigma的这段日子在技术方面感觉提高的方面可能就是脚本的编写吧,我感觉写一个可用的脚本,并不一定非的在于你对脚本有了多了解之后,然后再去实现一个切合实际的脚本,最主要是思路,当你对所需要使用的脚本工具有一定的理解(如:TCL),在一个实际环境,首先能有个明确的想法,想实现个具体的什么东西,怎么样的思路可以实现,大脑里具备了这些条件,就可以尝试去写一些脚本。当然了,在实现的过程中肯定会遇到这样或者那样的问题,但一般来说,基本都是一些对脚本语法以及命令不熟悉的原因造成,这些问题很好解决,可以跟熟悉脚本的同事讨论,来帮你解决当时的问题,所以,千万不要因为还没有开始,就将脚本看得非常困难,导致自己一直无法迈出第一步,其实有些东西还是比较容易实现的。所以在此将我写的几个脚本在此解读解读。文档目的这篇文档中所附带的脚本,主要是根据Sigma这边搭建的系统测试环境而撰写出来的,脚本内容可能与今后Sigma公司为我们所开发的系统测试脚本无关,当撰写完这几个脚本之后,各人感觉有些东西还是比较有价值的,因此本人将此脚本撰写为文档,将这些东西共享出来供大家分享、借鉴、参考,相信看完这篇文档,因该会提供很多切合实际测试的一些脚本开发思路。还有,这篇文档并非一篇解释TCL命令的文档,有许多脚本中的相关命令不熟悉的地方需要查找其它资料,部分命令只做了解释或者介绍。感谢!:)这些脚本的撰写过程中感谢小康同学与小井同学的帮助(很多地方错误的查找、以及提供了一些解决关键问题的命令,如果没有他们的帮助,这个脚本完成的难度就大了,有很多也是他们的功劳)环境介绍这里提到的环境主要介绍的是系统测试的物理网络TOP环境与逻辑网络TOP环境,因为脚本里面的内容跟这个具体环境有关:物理网络TOP,物理网络TOP所描述的实际是所有测试PC与DUT连接的物理线路图,实际物理TOP分为两个部分,控制网络与测试网络:(在这个实际环境中要求所有参与测试PC拥有两块可用的物理网卡,一块接控制网络交换机,另一块网卡连接测试网络交换机,测试网络交换机必须支持Vlan的划分,在某种特殊情况要求有trunk功能的支持,如测试网络交换机接口不足的情况,需要添加新的交换机,不同的交换机相同VLAN之间需要通信的需求,额外话题) 控制网络:我们可以从上图看到,所有PC的网卡eth1同在同一数据链路,IP也在相同网段,控制网络的目的是为了方便通过其中任意一台PC来控制其他的PC做一些事情,比如让某些PC在Testing网络建立一些连接,或者发送一些数据包,如何来控制,其实看完这篇文档实现的脚本,也就没有那么神秘了。 测试网络:实际这个网络就是专门构建我们DUT测试环境的网络TOP,根据划分VLAN创建不同的逻辑TOP。比如把DUT的某个接口eth0放入某个VLAN,将一些测试PC划入此VLAN,将DUT的另一个接口eth1放入另一个VLAN,其中此VLAN划入一些PC,这个TOP相当于DUT两个接口连接了两个不同,逻辑上的网桥。(一个VLAN相当于是一个独立的网桥)如下图,我们系统测试测试网络的逻辑TOP(列出供大家参考):从上图可以见到,在实际环境中搭建,至少可能需要六台交换机(少画两台),但在这个环境只用上来两台交换机,使用Vlan和Trunk实现。脚本介绍在做详细的脚本分析之前我们首先先对这些脚本做一个简单的介绍。这篇文档脚本实例中有部分是存在一定关系的,目的为执行不同的功能,但可以调用其它脚本执行所产生的变量。以下列出脚本的文件名称,对以下脚本的功能以及实现的目的做一个简单介绍: reach_host.tcl:检测控制网络存在的PC,将所有存在(可ping通)的PC放入一个变量形成一个列表。这个文档的目的是因为控制所有控制网络PC去做一些测试操作时,使用的都是IP通信,因此我们要保持测试网络的连通性,可能需要经常的去做一些ping的操作,因此做了一个这样的脚本来执行这件事情。这个脚本是借鉴Sigma的同事修改过来的,其他所有的脚本思路都是从这个脚本出发。这个脚本在这一系列脚本中,目的并不只是单纯的测试连通性,其实还有其他用途,比如我们的系统测环境所有PC分为四个区域,每个区域之间的PC的IP并不连续,我们可以通过这个脚本将所有可用的PC做成一个列表,将这个列表应用在其它的脚本。 setup_tools.tcl:这是一个单独得脚本,目的是将所有控制网络中可以Ping通的设备安装一些工具。(其实这个脚本可以扩展,只需要了解其他需要安装的linux软件步骤,即可向此脚本中补充,这里面只是拿出几个例子来提供一些思路) ipaddr_configure.tcl这个脚本运用到之前reach_host.tcl运行输出的控制网络存活PC的列表,然后在对这些列表中的PC配置eth0(测试网络)的IP地址。 hostname_configure.tcl(此脚本由老卢完成,脚本的解释后续添加) 这个脚本运用到之前reach_host.tcl脚本运行输出的结果(所有控制网络可连同PC的IP列表),然后在对这些列表中的PC配置主机名,但每个PC的主机名的第一个字符必须相关区域的字符,比如:A区的第2台PC IP地址为2,B区的第8台PC地址为8,我们根据相同颜色来分析他们的对应关系,A对10,B对20,C对30等(具体可以看系统测试TOP的IP列表)。 pc_list.tcl设置所有控制网络的IP变量,可以让其他脚本直接调用,使用其变量,避免每次新的脚本,使用到一些主机名字与IP对应关系得变量,每次都需要申明,避免麻烦就建立了一个这么列表。相当于在C语言中,我将所有需要经常用到的常量在一个文件中逐个define,然后其他的文件include。 traffic_control.tcl这个脚本可能是代码与内容最多的一个了(也是我最有成就感的一个)。这个脚本的目的是随时地控制TOP图中存在的任意PC与另一台PC建立任意通信(不过目前脚本中只是包含ping与ftp,要将其他的通性方式加入目前非常简单只需要将步骤往脚本中填入),在执行这个脚本时,只需相应主机控制网络存活,不需要了解测试网络中的IP地址,就可以让双方建立通信。比如:在这个系统网络中,如测试网络逻辑TOP(图二)所列出的PC,我只需要在其中某台PC运行此脚本,如FTP:./traffic.control.tcl A1 ftp A2 get aaa 10执行这个脚本的人不需要知道这两台主机的IP是多少(当然脚本会知道),就可以实现A1主机与A2进行FTP通信,get(可以put)一个aaa的文件,get这个操作循环10次忘了说明,这些脚本都由TCL结合Linux下的命令实现,对以上脚本做一个简单描述只是带领大家能对脚本产生一定的兴趣,其实当看了脚本之后,你们会感觉实际实现起来并非那么神秘,就只是将Linux下的命令调来调去!首先我们先进入第一个脚本的解释吧!!#/usr/bin/tclshset reach #设置变量reach,内容为空set unreach #设置变量unreach,内容为空set hostbase 10.11.105#因为我们所有ip的前三个字节相等,变化的只是第四个字节,因此将前三个字节放入变量for set i 11 $i” send “get test.txtr”expect “ftp” send “byer”以上是一个简单的expect过程,如果是用普通的shell脚本,其中包含ftp的通信过程,可能这一部分需要用户手动来输入相关信息。在这个脚本中,重要提到的是spawn、expect、send这几个关键字,至于语法可以按此例照搬。Spawn与expect是因该成对出现,通过spawn的执行相当与打开一个expect的通道,之后的expect结果将根据spawn后面所执行的命令来做一系列的交互式操作(在此例中通过spawn将针对ftp 做一系列的expect交互式操作)。当通过spawn打开此ftp之后,将有一个全局变量spawn_id被赋值,以上脚本为例,会将系统中此ftp运行的进程id赋值给spawn_id。当脚本执行ftp 之后,第二句脚本含义是将User (6:(none):字符串与expect中的buffer匹配(每当执行一个动作,会将系统输出信息放入expect_out(buffer)这个变量),如果匹配,将执行“”中send语句,将此内容向ftp进程送出,”r”代表回车。说白了就是当ftp后,如果出现字符串User (6:(none):,然后输入用户名yangfan回车到下一步,然后期待出现字符串Password:,将输入密码yangfan回车,然后如果出现ftp字符穿,继续输入get test.txt,最后在出现ftp的时候再输入bye退出ftp交互过程。简单讲述了上面的expect,我们继续看下面的脚本实例:在讲述在各脚本之前,我首先描述一下执行环境,我当时在在控制网络的某一个pc上执行的,我首先将需要安装的软件copy到我执行此脚本的pc/root/linuxtools目录中(在linux下可以通过scp这个命令将本地的文件cp到远程主机),我想通过脚本将此目录下所有软件包通过ssh拷贝到所有可以连通的测试网络PC上,我使用的这些安装包都是tar包,tar包需要首先通过tar命令解压缩,解完压缩后一般都是安装包相关的一个安装目录,所有安装文件都在目录下面,因此当时我已经在本地解完压缩,因此我只需要将我那几个安装包的目录cp到其它PC,然后远程进行安装,安装文件目录为一下几个 需cp到远程主机的目录:libpcap-0.9.4/ libevent-1.1a/ libpcap-0.9.4/ fragroute-1.2/vi setup_tools.tcl#!/usr/bin/tclshpackage require Expect#当脚本中使用到expect特性,需要注明以上set hostbase 10.11.105set hosts set reach set unreach for set i 11 $i下敲一个dir,目录打印出来后,最后的字#符串依然是C:),因此当执行到”#”又将开始执行ls,死循环开始了catch spawn ssh root$host a#做完上面的安装文件copy过后,在通过ssh登陆到这台设备(目的,是通过ssh在远程的pc上做#安装软件的操作),ssh root$host转变过来就是ssh root$10.11.105.x,root的意思表明用#什么用户登录,这是linux下的一个命令。expect yes/no send yesr;exp_continuepassword: send talentr;exp_continue#当登录完成之后expect # send cp -rf /root/linuxtools/libdnet-1.11 /usr/local/rexpect # send cp -rf /root/linuxtools/libpcap-0.9.4 /usr/local/rexpect # send cp -rf /root/linuxtools/libevent-1.1a /usr/local/rexpect # send cp -rf /root/linuxtools/fragroute-1.2 /usr/local/rexpect # send cd /usr/local/libpcap-0.9.4/rexpect libpcap-0.9.4# send ./configure&make&make installrexpect libpcap-0.9.4# send cd /usr/local/libdnet-1.11rexpect libdnet-1.11# send ./configure&make&make installrexpect libdnet-1.11# send cd /usr/local/libevent-1.1arexpect libevent-1.1a# send ./configure&make&make installrexpect libevent-1.1a# send cd /usr/local/fragroute-1.2rexpect fragroute-1.2# send ./configure&make&make installrexpect fragroute-1.2# send exitr;exp_continue#以上的实际整个步骤就是将cp到/root/linuxtools/下的工具安装目录在cp到/usr/local/下进#行安装,这个在安装软件过程中不是必要的,我的安装操作步骤繁琐了点,但我借介绍的只是#实现思路,其它的并不重要,但所有软件安装目录cp完了之后,在cd到每个软件安装目录下执#./configure&make&make install,这个是软件的安装命令,然后逐个的cd到不同的软件目录,#逐个的执行./configure&make&make install这条命令进行安装puts Host:$host fragroute is setup over!#然后再打印出某个Ip主机软件安装完毕实际到这一步我们可以看出,整个软件安装的思路: 取出需要安装软件的PC,在一个变量hosts中形成列表 通过foreach将hosts的Ip逐个取出放入host变量 将本地所有需要安装软件拷贝到host主机(通过expect与linux下scp这个命令实现) 通过ssh登录到host这台主机在host主机上进行安装软件(expect与linux 下ssh命令实现) 软件安装完毕,通过foreach在hosts变量中取得下一台需要安装软件的主机再作1-4描述的操作。其实如果明白了这个脚本的思路,后续的脚本是很容易看明白的,因此,后续的脚本中,一些雷同的步骤就不再做详细解释了。ipaddr_configure.tcl这个脚本目的是将所有控制网络中能连通的pc,eth0网卡配置上ip地址,但遵循一定规律,如下(别忘了,eth1上的ip地址已经手动配置好了):A区域PC 4eth1 IP 4eth0 IP GW B 区域PC 8 eth1 IP 8eth0 IP GW 也就是eth1 IP的第四个字节与eth0 IP的第三个字节相同(请参考我们控制网络的IP规律,图1已经全部标出)。下面这个脚本将会调用我们第一个实例的脚本reach_host.tcl。ipaddr_configure.tcl#!/usr/bin/tclshpackage require Expectsource /root/tclscript/reach_host.tcl#其实思路一样,给所有控制网络可以连通的设备做以下的操作,因为本身就有这么一个功能的#脚本存在(第一个案例),在这个脚本中,我们使用source命令首先来执行这个文件,这个脚#本将会产生一个变量reach(所有可以ping通PC的列表)供以下的命令使用,相当于c语言的#include语句.foreach host $reach puts Host $host start ip configure process:n#取出其中一个ipset ipaddr split $host .#通过split命令将Ip分割为列表赋值给ipaddr。如host中Ip为1,split通过”.”将此#Ip字符串分割为”10 11 105 11”赋给ipaddrset net lindex $ipaddr 3#从ipaddr列表中通过lindex取出第4个赋值给net变量(从0开始计算,因此为3)。catch spawn ssh root$host r#然后ssh登录在这台pcputs spid = $spawn_id n#这条语句在这个地方使用没有什么意义,只是为当时调试,不过spawn_id这边变量在某些情况#用的着,怕到时候忘掉这个单词,因此就把它留在这供以后查找set timeout 40expectyes/no send yesr;continuepassword: send talentrtimeout #通过ssh登录到这台主机expect # send echo DEVICE=eth0/etc/sysconfig/network-scripts/ifcfg-eth0r#登录后同样也是使用linux下的命令echo向/etc/sysconfig/network-scripts/ifcfg-eth0写入#配置信息,ifcfg-eth0这个配置文件保存的网卡的一些基本信息,可以通过修改此配置文件来修#改ip等基本信息,在这里需要注意的是,使用的是echo,后续使用的是echo,代表覆盖,这#里设计的含义是首先将之前这个配置文件中的信息通过第一条覆盖,后续的信息将通过追加的#方式来向这个文件补充信息expect# send echo ONBOOT=YES/etc/sysconfig/network-scripts/ifcfg-eth0rexpect# send echo BOOTPROTO=static/etc/sysconfig/network-scripts/ifcfg-eth0rexpect# send echo IPADDR=192.168.$net.2/etc/sysconfig/network-scripts/ifcfg-eth0rexpect# send echo NETMASK=/etc/sysconfig/network-scripts/ifcfg-eth0rexpect# send echo GATEWAY=192.168.$net.1/etc/sysconfig/network-scripts/ifcfg-eth0rexpect# send service network restartr#ifcfg-eth0的信息添加完毕之后,将执行linux下service network restart这条命令,来促使#上面的配置生效。expect# send exitr#然后在linux送出exit,退出登录的ssh,ssh进程结束,expect也就跟着结束puts Host $host ip configure was finished!in看完上面这个脚本,是否有新的想法来实现以下自己想实现的东西?接着介绍pc_list.tcl这个里面实际就是控制网络ip的列表,我在这里面定义了32个变量,每个变量对应一台主机,每个变量的内容是这台主机的实际IP,目的是位了让其它的脚本使用,免得每次都需要来给这些变量赋值。如:后续要介绍的traffic_control.tcl就会用到这个脚本。pc_list.tcl#!/usr/bin/tclshset A1 1set A2 2set A3 3set A4 4set A5 5set A6 6set A7 7set A8 8set B1 1set B2 2set B3 3set B4 4set B5 5set B6 6set B7 7set B8 8set C1 1set C2 2set C3 3set C4 4set C5 5set C6 6set C7 7set C8 8set D1 1set D2 2set D3 3set D4 4set D5 5set D6 6set D7 7set D8 8接着我们来说明以下traffic_control.tcl这个实例吧,但首先了解这个脚本的目的,我们可以看我们的测试网络的逻辑TOP(图二),我们只需要保证控制网络可连通,执行这脚本可以指定TOP中任意一台PC与另一台PC的进行通信(脚本中包含ping、ftp),执行脚本而并不需要知道测试逻辑TOP主机的IP地址。目前缺点是,测试网络的TOP搭建要求正确,而且每个目的主机需要提供相关服务,而且脚本只可以执行两台设备的通信,如果要主机之间的通信需要将此脚本分别执行多次,目前不支持一些排错信息。之前我的构想是:执行./traffic_control.tcl A1 ftp B2 get(put) filename 10当我执行这个脚本是A1对应得主机向B2对应的主机发起ftp通信,向B2上get或者put一个filename(可指定),然后指定这个get或put的动作做10次,首先了解我的想法然后我们在具体看这个脚本内容。A1 ftp B2 getput filename,均作为可选参数,ftp在此同样为一个可选参数。这个脚本可以在控制网络任意一台主机上执行。在设计这个脚本之前,我们来看看整个过程的思路:首先当用户输入脚本时 脚本需要知道输入这个两台主机相应的控制网络的IP。(pc_list已经定义) 通过控制网络ip,脚本至少必须知道发起通信目标主机的IP地址。(通过ssh上去取得) 判断通信类型,是ping还是ftp或者其它。(每一个通信类型都可以给不同数量或者内容的参数)思路就这么几条,但在实现的过程中却有很多问题需要等待解决,具体看下面脚本的解释吧!traffic_control.tcl#!/usr/bin/tclshpackage require Expectsource /root/tclscript/pc_list.tcl#执行这个pc_list.tcl脚本#source /root/tclscript/reach_host.tcl#这条命令无效,通过#注释无效proc trff_control #定义一个trff_control的过程global A1 A2 A3 A4 A5 A6 A7 A8 B1 B2 B3 B4 B5 B6 B7 C1 C2 C3 C4 C5 C6 C7 C8 D1 D2 D3 D4 D5 D6 D7 D8#因为之前执行的pc_list.tcl所有变量是个全局的变量,在过程中需要使用到的话需要在这个过#程中使用global声明一下set C_sou_hostname #控制网络的主机名,将来主动发起通信方set C_des_hostname #控制网络的主机名,将来主动发起方的目set C_sou_hostip #控制网络的ip,通信主动发起方set C_des_hostip #控制网络的ip,通信接受方set T_sou_hostip #逻辑网络的ip,通信发起方set T_des_hostip #逻辑网络的ip,通信接受方#定义部分变量,这样使得以后的编写过程中更容易区分set trff_type #设置通信类型,如ftp、ping、nc、nmap等等global argv argc argv0#因为argv argc argv0这三个变量是全局变量,在这个过程中需要用到此变量需要用global申明#一下set C_sou_hostname lindex $argv 0#我将脚本执行输入的第一个参数定义为发起方的主机名set trff_type lindex $argv 1#我将脚本执行输入的第二个参数定义为通信类型set C_des_hostname lindex $argv 2#我将脚本执行输入的第一个参数定义为接受方set arg1 lindex $argv 3set arg2 lindex $argv 4set arg3 lindex $argv 5set arg4 lindex $argv 6#定义其它的参数,考虑到今后通信类型的不同,参数也不一样,因此暂时定义了几个为将来通#信类型命令的参数先留着,少了在加,多了也没有关系set C_sou_hostip subst $C_sou_hostnameset C_des_hostip subst $C_des_hostname#subst这个命令很关键,因为这个命令解决了很大的问题,如果没有这个命令,可能这个脚本#就比较繁琐。比如,我们将通过lindex $argv 0得到一个字符串A1,然后又将这个A1字符串赋#给C_des_hostname,但我的目的是想输入的A1与我们这个脚本里定义的$A1联系起来,最终目#的是想当用户输入A1时,将$A1的ip直接赋值给C_sou_hostip,但TCL不支持set C_sou_hostip $C_sou_hostname#的方式,但只通过subst就很简单实现了,我在此说的是罗嗦了点!为什么?因#为当时如果不#是小康同学提供此参数,我走了很多弯路,因此在这强调一下。puts $C_sou_hostipputs $C_des_hostip#打印出刚才获取到的ipcatch spawn ssh $C_des_hostip rset C_des_id $spawn_id #将spawn_id值保存在C_des_id,在这里没有实际意义,在多个expect之间需要交互使用的情况下#是有用的set timeout 40expect yes/no send yest;exp_continuepassword: send talentrtimeout#通过ssh登录到接受通信的主机,目的是为获取逻辑网络eth0的ip地址#after 2000expect # send cat /etc/sysconfig/network-scripts/ifcfg-eth0r#通过expect察看eth0的ip地址,目的为expect_out(buffer)中会有ifcfg-eth0的信息expect # send rregexp .*IPADDR=(0-9+.0-9+.0-9+.0-9).* $expect_out(buffer) match T_des_hostip#通过reg

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论