Expect的一个简单使用
最近在写一个自动部署环境的脚本.发现shell在远程scp或ssh时.都需要提示输入密码.尝试建立server端的信任关系发现行不通(可能是基于安全考虑?)
不过,使用了另外一种方法解决了这个问题.它就是”expect”, 我觉得写有交互的shell还是挺有用的.现学现卖跟大家share一下.
什么是expect?
在做系统管理时,我们很多时候需要输入密码,例如:连接 ssh,连接ftp,
那么如何能做到不输入密码吗? 我们需要有一个工具,能代替我们实现与终端的交互
那么,就是它:expect,管理员的最好的朋友之一
Expect是在Tcl基础上创建起来的,它还提供了一些Tcl所没有的命令。spawn命令激活一个Unix程序来进行交互式的运行。 send命令向进程发送字符串。expect命令等待进程的某些字符串。 expect支持正规表达式并能同时等待多个字符串,并对每一个字符串执行不同的操作。expect还能理解一些特殊情况,如超时和遇到文件尾.
expect命令和Tcl的case命令的风格很相似。都是用一个字符串去匹配多个字符串。(只要有可能,新的命令总是和已有的Tcl命令相似,以使得该语言保持工具族的继承性)。命令格式如下:
expect patlist1 action1 patlist2 action2.....
该命令一直等到当前进程的输出和以上的某一个模式相匹配,或者等到时间超过一个特定的时间长度,或者等到遇到了文件的结束为止。
每一个patlist都由一个模式或者模式的表(lists)组成。如果有一个模式匹配成功,相应的action就被执行。执行的结果从expect返回.
安装expect
因为expect是基于tcl的,所以需要系统先安装tcl.
查看tcl是否已经安装 执行:” whereis tcl”
当前yum上就有个5.42.1版本.
expect.x86_64 5.42.1-1
没装的话装上就可以了
使用expect
下面用几个脚本演示下expect的使用
scp.sh
#!/usr/bin/expect -f
expect -c "
set timeout 1200;
spawn /usr/bin/scp -r $1 $4@$2:$3
expect {
\"*yes/no*\" {send \"yes\r\"; exp_continue}
\"*Password\" {send \"$5\r\";}
}
expect eofi;"
ssh.sh
- 脚本中给定一个超时时间.这个约束用户必须在多久时间内进行输入.
- 调用spawn启动命令的会话,参数使用与shell一致.
- 决定如何响应.这里使用了正则表达式.针对不同响应发送不同的消息.
比如上面的scp.sh 和ssh.sh.
我们可以在下面的shell中直接调用.
sh scp.sh test_scp001 v039166.sqa.cm4 /home/shichengfeng.tw/ shichengfeng.tw shicf1204
当然,expect还可以解决更多的交互式问题,比如自动telnet,ftp等,并可以支持更多的语法.这里不再一一罗列.赶兴趣的同学可以继续研究.