Here Documents 结合expect的使用--总结篇
总结:
-
如何打开expect的log, 怎么使用log ?
打开expect的log非常简单,只需要定义变量log_file , 格式为: log_file /tmp/exp_log, 其中后面的/tmp/exp_log是你自己设置的log文件的路径,log对于查找是否发生了匹配错误非常的重要;
通常对于复杂的匹配,个人更倾向于先把 log打开,然后对照log, 再去修改expect的匹配表达式,这种方式对于提高工作效率要有不少的帮助 -
expect是对输出的哪一部分进行匹配的?
expect进行匹配的时候,总是从上一次成功匹配的位置开始,到spawn出来的子进程产生的最新输出(包含使用send所发送的命令的回显,当然也包含被执行命令的结果)为止,把这一段的内容用来做匹配,并不是拿所有的输出来用做匹配的 -
使用正则表达式的时候,到底怎么理解正则的匹配范围?
用expect进行正则表达式匹配的时候,最好使用分组模式,可能比较常见的有类似
\r\n(.*)\r\n(.*)\r\n(.*)~] 这样的模式 , 对于这个正则表达式的理解如下:
因为(.*) 表示任意匹配,所以这个到底是 适用于“最小”范围匹配,还是适用于“最大”范围匹配呢?这里应该是“最大”范围匹配,但是大到哪里呢?
大到没法满足正则表达式为止,所以这个范围的确定需要从表达式的后面向前进行分析, 把从后到前的所有的精确匹配作为分界条件(在这个表达式中的精确匹配是:3个换行符,以及字符串 "~]"),然后尽可能 的从前向后 依次最大化满足每一个(.*)的匹配;
那么问题又来了,如果后面有多个"~]",那么又会是“最小范围匹配呢” , 还是“最大范围匹配”, 这个依然是最大范围匹配;
理解正则表达式的匹配规则 对于使用 expect有很好的帮助; -
使用正则匹配的时候,如何获取特定分组的结果?
在使用正则表达式来进行匹配的时候,通常会用小括号来进行分组,比如上面第三条描述的正则表达式就包含了三个分组,那么要获取分组的内容,可以用 $expect_out(NUMBER,string)的方式获得,如果number为0,那么就获取所有的分组内容,不在分组中的部分不会被获取。 -
expect_out保存了什么内容?为什么可以通过expect_out来获取命令的输出结果?
$expect_out(buffer) 的内容来自于‘两个标记之间的内容’,这两个标记分别是:当前的expect中匹配上的字符串的末尾,前一次expect中匹配上的字符串的末尾。
而命令的输出结果,如果被包含在 两个expect之间的话,那么 命令的结果也就保存在expect_out中了,所以可以用来获取命令输出的结果; -
使用send发送的命令,其命令回显是否会被expect用来做匹配?
send 发送的命令如果有回显,那么回显也是会被expect用来进行匹配的;对“回显”的理解:
比如输入密码的时候,虽然输入了,但是屏幕上并没有出现输入的字符,这就是没有回显;
而对于输入的命令,都是有“回显”的,这一点在匹配的时候要特别注意;
另外,如果连续使用send 发送多条命令,比如send "ls\r" ; send "cat /etc/os-release" ,那么被expect捕获的顺序是(以下是伪代码):
[:prompt] ls
'ls'命令的结果;
[:prompt] cat /etc/os-release
'cat /etc/os-release的结果';
-
如果命令输出结果非常的大,那么用expect_out获取到的内容就不完整,默认只有后半部分,怎么获得完整的结果?
通过full_buffer 来进行处理,当expect_out中存储的内容已经达到最大的时候就会触发 full_buffer匹配,这时候通常 把expect_out(buffer)中的内容追加到自定义的变量中,然后使用exp_contine 让expect处理继续;具体使用见 文章 <<Here Documents 结合expect的使用--(3)>>.
本文原创,转载请注明出处