1.需求
某服务器主控板连接着128个智能芯片,需要ssh到每一个芯片的系统上面去检查外部网路的连通性,以及看看是否被主控板校时,内部时间一致。人工测试类似的用例每条都要执行128次,假设一次连贯操作至少30秒,匀速测完需要耗费1个小时4分钟。
2.except语法简单介绍
我们通过shell可以实现基本控制流功能,如:循环、判断等。但是对于需要交互的场合则必须通过人工来干预,有时候可能会需要实现和ssh、telnet、FTP等程序进行交互的功能,单纯的shell就无能为力了。而expect就是用来实现这种功能的工具,它是一个用来处理交互的命令。借助expect,我们可以将交互过程写在一个脚本上,使之自动化完成。
网络上找不到成系统的except语法解释,参考各种代码片段,上面需求的expect脚本可以写成下面的形式,保存为KT_ssh_login.exp。
except脚本可以单独保存成文件被shell调用,也可以作为片段嵌入到shell文件中。
解释器
必须在首句指明解释器 ,注意这里的解释器是expect不是shell。另外选项在此脚本中可以省略。
变量与超时时间
定义变量使用关键字,外部变量用表示。
设置超时时间(单位秒)用于等待无响应或者时间过长的情况下中断,例如在ping外部网络不通的时候,ping命令自身超时时间较长,设定5秒后主进程直接中断这个过程。当timeout设置为-1时表示永不超时。
spawn
关键字用来启动新的进程。spawn后的send和expect命令都是和spawn打开的进程进行交互的。这里spawn打开了ssh登录的子进程。
expect和send
关键字通常是用来等待一个进程的反馈。expect可以接收一个字符串参数,也可以接收正则表达式参数。关键字命令接收一个字符串参数,并将该参数发送到进程。这两个关键字成对出现的意思是,从标准输入中expect到目标字符串后,向标准输出send需要的内容,从而实现交互的过程。
代码中第一个expect是一种多分支模式的写法,因为第一次ssh时会需要确认输入yes后再输入密码,之后如果设备未重启,再ssh的时候就没有这个确认过程了。关键字表示前后两个expect到的内容是串行关系,而第二个“password”前没有这个关键字,所以第二个“password”与前面接收到的“yesno”、“password”是并列关系。
send命令的时候,后面需要加上转义字符r表示一个回车,否则命令不会执行。
interact和eof
如果需要停留在ssh,可以使用关键字,这样后续会等待用户手动交互。这里直接退出expect,使用关键字
3.shell的实现
expect的一个局限在于内部无法进行比较复杂逻辑判断,所以检查判断的活交给shell来完成。但是expect也没办法把一些信息直接返回给shell,所以这里只能用命令将交互的内容保存后做文本解析。通过判断字符串是否出现检查网络状态,通过年月日时分是否与主控板一致检查校时。
失败时会直接中断并提示错误如下。
成功128个芯片需要9分钟左右,成功提示如下。
领取专属 10元无门槛券
私享最新 技术干货