1.如何实现在一个变量后面紧跟着一个字符串, 中间没有空格. set p "hi" puts [set p]hello 其实,还可以这样来实现 puts ${p}hello 2.在proc里面直接return(后面没有带参数), 那么proc将会直接返回, 不会返回任何值. 否则, 将会返回最后一条语句的执行结果的返回值. 3.exit在任意的地方都能够退出tclsh的执行程序, 返回到shell. 4.proc一旦被定义, 它可以被任何proc所调用, 包括它自己----就是相当于递归调用(recursive) 5.concat与list的区别---- % concat a b "hello world" a b hello world % list a b "hello world" a b {hello world} % 6.Causing Errors. 一般在proc里面, 产生某个错误, 并能够产生相对应的错误信息, 在外层程序使用catch来检测错误. error命令. 7.expect的timeout时间, timeout是以秒为单位, 如果设置为0, 是根本就不等待, 设置为-1, 是永远等待. 8.想要取得没有匹配的expect数据, 怎么做? 就是expect后timeout出来后, 数据不会存储在expect_out(buffer)里面. 可以再次使用一次expect *, 然后读取expect_out(buffer). 9.expect里面的timeout一直是作为关键字的, 即使它被双引号括起来. 10.expect 的eof的含义, 相当于匹配process的结束符, 如果匹配不到(在expect期间如果process没有结束,它就会timeout), 这也就是为什么如果使用expect eof会变得慢的原因. 如果程序没有结束, 它将会等待默认的10秒钟.如果expect的过程中, 检测到process的eof, 它会返回的.如果有pattern eof, 它就会执行相应的脚本. 否则直接返回. 11. expect的default 相当于匹配了timeout和eof 12. expect的spawn了一个process, 如果结束了, 它会返回给expect一个eof信号, 反过来, expect也可以主动来关闭spawn的process, 这时候,process也会看到一个eof信号, 一般来说, process收到这个信号后, 它会主动关闭它自己. 13. 使用expect的re来匹配正则表达式, 那使用什么来表示glob匹配呢? 默认的就是使用glob来匹配, 也可以使用显式的-gl来声明使用glob.假如要匹配一些expect的关键字, 例如eof, default, timeout等, 就可以使用-re或者-gl来表示. 如果在使用glob的时候, 如果匹配的pattern里面有变量, 最好加上-gl, 防止由于变量的值为expect的关键字或者标志. 14. atom, pieces, branch. a a+ [0-9][a-z]+ 15.在expect里面"()"有两个作用, 一个是override precedence, 例如(ab)+, 它就会匹配ababab, 多个ab; 另一个作用就是收集匹配"()"里面的数据到expect_out里面 在expect里面使用()来收集匹配的数据.示例如下: -echo -re "$key_array(switch)\[1-9\]\[0-9\]*\r" { set leninteract [string length $interact_out(0,string)] set idindex [string range $interact_out(0,string) 1 [expr $leninteract - 2]] ... } 这样写的效果是一样, 很显然, 下面的写法很简洁. -echo -re "$key_array(switch)(\[1-9\]\[0-9\]*)\r" { set idindex $interact_out(1,string) ... } 16. expect匹配的时候规则: a) 尽可能在字符串开始的位置进行匹配.(match at the earliest possible position in the string)[在这里, 值得注意的时候, 对于正则表达式而言, 它是首先使用第一个正则表达式来匹配所有字符串, 然后再使用第二个表达式来匹配.因此, 对于同一个字符串能够同时匹配多个正则表达式的, 总是第一个正则表达式被匹配上.] b) 最左边的匹配规则首先被使用.(the left-most matching branch is used) (在实际测试发现是最长的被匹配,例如表达式a|ab, 输入ab, 匹配的是ab,而不是a) c)最长的匹配被使用.(the longest match is used) 例如a*匹配最多的a, 而不是"". d)子表达式是从左到右进行匹配的.(subexpressions are considered from left to right) 17.expect里面嵌套的括号, 是如何存储在expect_out里面的呢? 是根据从左到右数左边括号的次序来进行的. 18. 匹配一个$, 需要三个\, 为什么呢? 匹配一个\, 需要在前面加上三个\. 19. expect里面有-ex选项, 是用来精确匹配的, 会将*, ., $, ^等等都当作一般字符来处理的, 这样就不用使用复杂的\来转义啦. 20. 匹配一行并且只匹配一行. 例如搜索到第一行就立即退出程序. expect + tcl is powerful. it is easy for tcl and expect, but it is very painful for other program such as c, perl, shell 21. 在进行expect匹配的时候, 如何忽略匹配字符的大小写. 使用-nocase参数, nocase是将字符串转换成小写来进行匹配. Uppercase characters in the pattern can never match. 22. 让人难以相信的是expect居然提供了内部调试命令exp_internal来查看它的匹配过程. too powerful. 用法: exp_internal 1打开, exp_internal 0关闭. 值得注意的是: exp_internal的输出是作为标准错误输出的, 可以使用shell的重定向技术来将标准错误输出和标出输出进行分离. 23. log_user能够隐藏spawn的process的输出. 24. log_file能够将将Expect所有的输出都记录到一个文件里面去.但是它不能够将tcl的输出打印到文件里面去. 对于这个, expect的作者是建议使用send_user而不是使用puts来输出信息. 值得注意的是, send_user在打印信息的时候, 不会加上一个新行. 用法: log_file <filename> 开始记录 log_file 关闭记录(不带参数的log_file) 25.puts在打印的时候默认会打印一个新行, 可以加上-nonewline参数来不让它打印新行. 26.expect_user 从标准输入读取数据. expect如果没有spawn一个process是和expect_user相同的. 27.send_slow, 用来向process发送数据的慢一点. send_slow (2 0.01) 每隔0.01秒钟发送2个字符. 用法:set send_slow {2 0.01}; send -s $text 28.面向行的终端模式: 是指字符在没有按回车之前不会送给script.在按了回车后, 它会将回车(\r)转换成换行(\n). 面向字符的终端模式: 是指按下一个字符就送给script, 它不会转换换行. 因此在匹配回车的时候, 要使用\r, 而不是\n, 面向字符的模式, 如果输入错了字符以后, 是无法编辑删除的. stty raw 面向字符 stty -raw 面向行 这两种终端模式都有echo和不echo方式. stty echo stty -echo 29. 使用Expect的system命令来执行unix/linux系统的命令. 类似于了tcl的exec命令. 注意它与exec的区别. 基本上可以这样认为: eval exec ... 等于 system ..., exec 会将参数列表当作一个参数传递给shell, 而system使用的concat机制来传递给shell. 30.expect_tty和expect_user的区别, expect_user能够被shell所重定向. 而expect_tty则是永远指从键盘读取输入. send_tty和send_user的 情况类似. 31. expect 的flag, -c在执行脚本之前执行一个命令, 建议在tcl文件的前面一行使用#!/usr/bin/expect 32. 可以使用expect的interpreter命令来转换到交互式模式下. 这样在脚本没有完成的时候, 就不需要输入exit. 这个功能对于调试程序能够带来很大的方便.比如说, 在我怀疑出现问题的地方我加上一个interpreter, 然后可以puts任意的变量, 当需要继续执行的时候, 使用return返回到script, 继续执行下面的script. 这样就不需要在中间输入exit. 33. 三个预定义的spawn_id, user_spawn_id, error_spawn_id, tty_spawn_id, 可以将spawn_id设置成user_spawn_id, 这时候, expect就从终端中读取信息和输出信息. 34. expect -i $list 和expect -i list的区别, 后者, 更方便使用一些, 原因在于, 如果在执行expect的过程中, list值变化的话, 对于后者, 他是能够自动适应的, 而前者, 还会使用已经删除了某个元素的list. 35. 可以使用exit -onexit { }来实现在exit退出的时候, 执行某些命令, 例如打印信息"bye bye", 或者删除文件临时文件. 避免在每次退出的时候都敲那些命令. 同时, 他可以使用exit -noexit {}来关闭它. 36. 可以捕获SIGINT信号, 这样当用户按ctrl + c的时候, 可以做想做的的事情. 37. interact默认的匹配是采用的exact匹配, 也就是说, 相当于 expect带上了-ex参数. 38. interact的-o参数, 是表示从spawn的process中读取匹配的信息.在-o以后的表达式都表示从spawn process中读取信息. 因此, 要特别注意它的位置. 39. interact没有interact_out(buffer)这个变量. 40. 如果interact里面同一个字符串匹配了多个表达式, 它只会执行第一个表达式的action. 41. interact里面支持return退出interact操作, 也可以使用while或者for循环, 然后使用break或者continue命令来退出interact 42. interact里面也可以检测到spawn的process的eof标识.interact -o eof. 值得注意的时候, 如果要检测eof标记, 必须在处理程序里面执行return命令, 否则, 执行了eof的action以后, 程序它会进行来执行interact. 这样, 它就会出错的. 43. interact的timeout和expect的timeout不同, 它不是基于timeout变量的. 它是这样的: interact timeout 3600 { } 44. interact的-u和-i标记, 能够实现两个process互相输入和输出. -input 和 -output标记 45. interact也可以从多个spawn_id进行输入, 但是它不会自动设置interact_out(spawn_id), 而是需要设置-iwrite标记.