目录
引子:初见TCL
基本命令
置换命令
普通置换
变量置换
命令置换
反斜杠置换
其他置换
脚步命令
eval命令
source命令
语言命令
简单变量
数组变量
重构变量及其操作
补充概念
全局变量和局部变量
小结
最近突然遇到了要用TCL脚本语言操作的需求,找资料的过程中发现资料都是零零散散的,再看完很多文档之后,重新归类整理了一下,个人认为整理的还是比较清晰,是先从较为简单和常用的置换命令开始分析,然后再到语言命令的使用,降低了入门的难度,也利于使用的时候查阅,最后也整理出了思维导图版本可供使用。
引子:初见TCL
TCL(tool command language)用于描述脚本,仿真的网络环境和参数设置,也称“踢叩” "tickle"。我觉得他的语言思路和linux的终端命令有点像,基本就是操作符+变量这样子,省去了很多字符修饰。
下面将介绍一下常用的命令集,以及遇到的常见问题,可以在目录中快速跳转,建议收藏一下方便速查~
基本命令
置换命令
置换命令可以当作C语言中的赋值来理解,但是又有点不一样,因为这个置换不需要定义类型,可以直接赋值,所以引入了新的规则,来让机器知道每个字符或者数字到底需要做什么,可以按照下面的思路学习。
普通置换
set x 10set y 100 + x //命令执行后,y的值是“100 + x”而不是我们期望的110
Tcl解释器在分析命令时,把所有的命令参数都当作字符串看待,所以x 被看作了字符串“100 + x”的一部分。如果我们想使用x的值'10' ,就必须告诉Tcl解释器:我们在这里期望的是变量x的值,而非字符'x'。怎么告诉Tcl解释器呢,这就要用到Tcl语言中提供的置换功能。置换可以发生在包括命令名在内的每一个单词中,而且置换可以嵌套。
变量置换
set x 10set y 100 + $x //这时,y的值还不是我们想要的值110,而是100+10
变量置换由一个$符号标记,变量置换会导致变量的值而非变量(标识符)本身被插入到字符串中。因为Tcl解释器把10+100看成是一个字符串而不是表达式;y要想得到值110,还必须用命令置换,使得Tcl会把100+10看成一个表达式并求值。
命令置换
set x 10set y [expr 100+$x] //这时,y的值就是110了
命令置换是由 [ ] 括起来的TCL命令及其参数,这里当Tcl解释器遇到字符' [ '时,它就会把随后的expr(下图解释)作为一个命令名,从而激活与expr对应的C/C++过程。命令置换会导致某一个命令的所有或部分单词(参数)被另一个命令的结果所代替,并把expr命令中变量置换后得到的'10+110'传递给该命令过程进行处理。注意,[ ]中必须是一个合法的Tcl脚本,长度不限。[ ]中脚本的值为最后一个命令的返回值。
补充:expr 后面的两个参数接“比较符”,类似[a 比较 b ? a :b],为运算符则为普通运算。
反斜杠置换
set msg multiple/ space
如果没有'/'的话,Tcl会报错,因为解释器会把这里最后两个单词之间的空格认为是分隔符,于是发现set命令有多于两个参数从而报错。加入了'/'后,空格不被当作分隔符,'multiple space'被认为是一个整体。【毕竟TCL语言没有 ; 的要求】
其他置换
除了使用反斜杠外,Tcl提供双引号” “和花括号 { },使得解释器把分隔符和置换符等特殊字符当作普通字符而不作特殊处理。
but!不同的是:
- TCL解释器对双引号“ ”中的各种分隔符将不作处理,但是对换行符及$和[]两种置换符会照常处理。
- 而在花括号{ }中,所有特殊字符都将成为普通字符,失去其特殊意义,Tcl解释器不会对其作特殊处理
脚步命令
这个没有太多的东西,常用的主要有两种命令(可以留言补充)
eval命令
eval arg arg ...
接收一个或多个参数,然后把所有的参数以空格隔开组合到一起成为一个脚本,然后对这个脚本进行求值
source命令
source e:/tcl&c/hello.tcl(例子)
读一个文件并把这个文件的内容作为一个脚本进行求值。注意路径的描述应该和UNIX相同,使用' / '而不是' / '
学完了上面的一些规则之后,下面还要完善一下常用的命令基础
语言命令
虽然TCL语言有自己独特地用法,但是咱们最好还是按C/C++语言中标识符的命名规则命名,这样不仅方便理解,也能减少冲突概率,有了上面的概念基础部分之后,语言命令这部分,咱们就由浅入深地聊聊~
简单变量
set a 2 //将2赋值给aset a.1 5 //名字和值都可以是任何字符串set b $a.1 //我们希望把变量a.1的值付给b,但是结果不是set b ${a.1} //强大的花括号,实现上一条的想法
Tcl解释器在分析时只把 $ 符号之后直到第一个不是字母、数字或下划线的字符(这里是 '. ')之间的单词符号当作要被置换的变量的名字,所以TCL解释器把a置换成2,然后把字符串“2.1”付给变量b。这显然与我们的初衷不同。当然,如果变量名中有不是字母、数字或下划线的字符又要用变量置换,可以用花括号把变量名括起来。
数组变量
set day(monday) 1 set day(tuesday) 2
数组是一些元素的集合。TCL的数组和一般编程语言中的数组有很大的区别。在TCL中,不能单独声明一个数组,数组只能和数组元素一起声明。数组中数组元素的名字包含两部分:数组名和数组中元素的名字,Tcl中数组元素的名字(下标〕可以为任何字符串。
重构变量及其操作
fomat命令
set msg [format "%s is %d years old" $name $age]
format命令类似于ANSIC中的sprintf函数,它按formatstring提供的格式,把各个value的值组合到formatstring中形成一个新字符串,并返回。
scan命令
scan "some 26 34" "some %d %d" a b
scan命令可以认为是format命令的逆,其功能类似于C中的sscanf函数。它formatsting提供的格式分析string字符串,然后把结果存到变量varName中,注意除了空格和TAB键之外,string 和formatsting中的字符和'%'必须匹配。
string命令
string length stringstring range string first laststring index string charIndexstring tolower string [first] [last]string replace string first last [newstring]string equal [-nocase] [-length int] string1 string2string match [-nocase] pattern string //如果pattern 匹配string,那么返回1,否则返回0.string compare [-nocase] [-length int] string1 string2 //如果有 -length 参数,那么只比较前 int 个字符string first string1 string2 [startindex] //在string2 中从头查找与string1匹配的字符序列,如果找到,那么就返回匹配的第一个字母所在的位置(0-based)。如果没有找到,那么返回-1。string trim string [chars] //返回值为:从string字符串的首尾删除掉了字符集合chars中的字符后的字符串。如果没有给出chars,那么将删除掉spaces、tabs、newlines、carriage returns这些字符.
string命令具有强大的操作字符串的功能,并通过其中的subcmd来区别具体将要执行的string操作。
list相关命令
list [ value value...] //这个命令生成一个list,list的元素就是所有的valueconcat list [list...] //这个命令把多个list合成一个listllength list //返回list的元素个数lindex list index //返回list的第index个(0-based)元素lrange list first last //返回list的第first (0-based)到第last (0-based)元素组成的串,如果last的值是end。就是从第first个直到串的最后linsert list index value [value...?] //返回一个新串,新串是把所有的value参数值插入list的第index个(0-based)元素之前得到
补充命令
这一部分没有怎么用到过,但是为了方便查询,也给加上了,以后万一需要呢。
补充概念
全局变量和局部变量
对于在过程中定义的变量,因为它们只能在过程中被访问,并且当过程退出时会被自动删除,所以称为局部变量;在所有过程之外定义的变量我们称之为全局变量。TCL中局部变量和全局变量可以同名,两者的作用域的交集为空:局部变量的作用域是它所在的过程的内部;全局变量的作用域则不包括任何过程的内部。这一点和C语言有很大的不同。如果我们想在过程内部引用一个全局变量的值,可以使用global命令。
缺省参数和可变参数
可以定义具有缺省参数值的过程,我们可以为过程的部分或全部参数提供缺省值,如果调用过程时未提供那些参数的值,那么过程会自动使用缺省值赋给相应的参数。和C/C++中具有缺省参数值的函数一样,有缺省值的参数只能位于参数列表的后部,即在第一个具有缺省值的参数后面的所有参数,都只能是具有缺省值的参数。
TCL的过程定义还支持可变个数的参数,如果过程的最后一个参数是args, 那么就表示这个过程支持可变个数的参数,位于args以前的参数象普通参数一样处理,但任何附加的参数都需要在过程体中作特殊处理,过程的局部变量args将会被设置为一个列表,其元素就是所有附加的变量。如果没有附加的变量,args就设置成一个空串。
引用概念
upvar [level] otherVar myVar otherVar myVar ...
upvar命令使得用户可以在过程中对全局变量或其他过程中的局部变量进行访问。upvar命令的第一个参数otherVar是我们希望以引用方式访问的参数的名字,第二个参数myVar 是这个过程中的局部变量的名字
proc temp { arg } { upvar $arg b set b [expr $b+2] } proc myexp { var } { set a 4 temp a return [expr $var+$a] }则: myexp 7 13
一旦使用了upvar 命令把otherVar 和myVar 绑定,那么在过程中对局部变量myVar 的读写就相当于对这个过程的调用者中otherVar 所代表的局部变量的读写。这上面的例子中,upvar 把$arg(实际上是过程myexp中的变量a)和过程temp中的变量b绑定,对b的读写就相当于对a的读写。
upvar 2 other x
upvar命令语法中的level参数表示:调用upvar命令的过程相对于我们希望引用的变量myVar在调用栈中相对位置,这个命令使得当前过程的调用者的调用者中的变量other,可以在当前过程中利用x访问。缺省情况下,level的值为1,即当前过程(上例中的temp)的调用者(上例中的myexp)中的变量(上例中myexp的a)可以在当前过程中利用局部变量(上例中temp的b)访问。
upvar #0 other x
要访问全局变量可以这样写,不管当前过程处于调用栈中的什么位置,都可以在当前过程中利用x访问全局变量other。
小结
一般来说,TCL语言是IC方向设计或者测试应用的一门重要语言,在linux/unix系统在上面写bash shell脚本程式也经常用到,想要学习和建立更好的测试环境,我们需要了解脚本中一些常用的语句和用法。虽然我现在用到的还不是很多,但是也先整理了下来,先大体学习一下,后面再逐步加深印象,不同语言和程序之间有很多思路都是相通的,多接触一门语言也会让我们的思维更加开阔。
有些函数目前还没有用到,所以也不敢过多注释,后期会随着使用逐步完善,如果有需要调整的地方还请指正,不胜感激!
最后是整理的一图速查版本,上传图片大小有限制qwq,如果看不清的话可以找我重新发给你,应该是基本都考虑到了