-
当你执行expect脚本send一条命令的时候,会触发一次匹配动作
这个特性导致当你的命令中存在要匹配的关键字时,命令不会执行,而是永远能够匹配,进而影响预期执行效果!
该特性通过执行expect -d打印debug信息能够观察到(可以通过清除缓存避免该问题) -
-re参数标识使用正则表达式匹配。使用正则表达式的时候,最好先用debug模式看一下具体匹配的内容到底是什么,再根据内容写对应的正则表达式
-
输出子进程的返回码expect eof{
catch wait code
exit [lindex $code 3]
} -
wait负责子进程善后工作,expect脚本中循环调用spawn,一定要在eof或者close之后调用wait来完成子进程的清理。
-
如果脚本设置超时,但是没有用timeout匹配,在外部的wait会一直等待直到spawn完成退出。
-
expect脚本如果当前expect没有匹配到,会继续往下执行后面的匹配(需要分析)
-
多条send命令会并行执行,其下的expect可能会匹配这些send的任意一个。如果需要多条并行,建议使用shell的管道符拼接的方式。如果要串行,最好一条send一条expect。
-
expect中的sleep,如果sleep和send同时执行,sleep会使整个expect的输出卡住,但是实际上send已经执行了,这点要注意。
-
expect脚本中send和send_user行位结束符的区别:send可以使用\r或者\n,send_user只能使用\n(究其原因,是因为\r在linux中代表移至行首,\n为换行,然后移至行首。如果send_user使用\r会造成输出被覆盖)
-
timeout和eof应该对应的是某个expect,也就是说,每个expect模块都应该设置timeout或eof响应行为
-
一个expect模块对应一次动作执行,如果把所有的expect放在脚本最外层,那么在spawn后,会如果第一个expect没有匹配到,会继续向下匹配,每个都超时(没匹配到的情况下)
-
eof:当spawn新起的线程终止时(可以模拟kill即可),接受到eof信号,触发当前expect中的eof,把eof定义到全局是错误的行为,会报can not find channal named.
一次expect进入之后,可以定义eof,如果没匹配到会直接执行本expect定义的eof的行为 -
打印控制台输出:$expect_out(buffer)
-
scp等执行完就结束的进程,可以直接通过捕获eof来判断是否执行完成
-
match_max可以设定expect_out(buffer)的缓存去大小,默认2000字符,一旦命令输出超过2000字符,前面的字符会被丢弃
-
在多条件匹配时(一个expect里面多个表达式),expect会丢弃已经匹配的文本(或者说会在已经匹配到的文本末尾打个标记),当exp_continue再次进入时,会从标记位置往后继续匹配。也就是说,匹配的不是$expect_out(buffer)
参考(电脑打开):https://my.oschina.net/jianglibo/blog/656608
要注意的是,spawn打开的线程,在命令结束后不再匹配,也就是说当你通过spawn执行echo命令的时候,他只能匹配一次,后续不能再匹配。因为ssh本身是连续交互式的命令,所以可以有多个expect