痛点:
现在有两台Linux主机A和B,如何从A主机ssh到B主机,然后在B主机上执行命令,如何使这个过程实现全程自动化?你可能会使用这种方法:
ssh admin@10.220.20.15 "ls"
但是这种方式比较笨拙,每次都要输入密码,同时并不能执行一些复杂的逻辑或命令。那么如何实现全程自动化呢?这就要用到今天这篇文章总结的expect了。
expect是什么?
expect是一个免费的编程工具,用来实现自动的交互式任务,而无需人为干预。说白了,expect就是一套用来实现自动交互功能的软件。
在实际工作中,我们运行命令、脚本或程序时,这些命令、脚本或程序都需要从终端输入某些继续运行的指令,而这些输入都需要人为的手工进行。而利用expect,则可以根据程序的提示,模拟标准输入提供给程序,从而实现自动化交互执行。这就是expect!!!
expect基础
1.send
命令接收一个字符串参数,并将该参数发送到进程。
2.expect命令和send命令相反,expect通常用来等待一个进程的反馈,我们根据进程的反馈,再发送对应的交互命令。
3.spawn命令用来启动新的进程,spawn后的send和expect命令都是和使用spawn打开的进程进行交互。
4.interact命令用的其实不是很多,一般情况下使用spawn、send和expect命令就可以很好的完成我们的任务;但在一些特殊场合下还是需要使用interact命令的,interact命令主要用于退出自动化,进入人工交互。比如我们使用spawn、send和expect命令完成了ftp登陆主机,执行下载文件任务,但是我们希望在文件下载结束以后,仍然可以停留在ftp命令行状态,以便手动的执行后续命令,此时使用interact命令就可以很好的完成这个任务。
案例分析
就以上一篇文章批量添加主机为例,我们通过zabbix—api接口批量添加了主机,但是还是没有完成,需要在被监控主机上添加agent,如果一个个添加工作量很大,所以在这里用上正好合适。
#!/bin/bash
user=linfan #主机用户名
pass='linfan123' #主机密码
for ip in `cat iplist.txt` #文件中放着需要执行命令的主机IP
do
/usr/bin/expect << EOF
set timeout 3 #链接超时3秒
spawn scp /home/linfan/zabbix_xiufu.sh $user@$ip:/home/linfan/#将要执行的脚本传到需要执行命令的主机
expect {
"(yes/no)" {send "yes\r"; exp_continue}#出现“yes/no”的字样,就自动输入“yes”其中exp_continue表示循环式匹配,通常匹配之后都会退出语句,但如果有exp_continue则可以不断循环匹配,输入多条命令,简化写法。
"password:" {send "$pass\r"}#出现“password:”字样,就自动输入密码
}
spawn ssh $user@$ip #远程切换到执行命令的主机中
expect {
"password:" {send "$pass\r"}#出现“password:”字样,就自动输入密码
}
expect "$user@*" {send "sudo chmod 755 /home/linfan/zabbix_xiufu.sh\r";}#出现“用户名@任何的”字样 就给与脚本执行权限
expect "$user@*" {send "sudo /home/linfan/zabbix_xiufu.sh\r";}#出现“用户名@任何的”字样 就执行脚本
expect "$user@*" {send "exit\r"}##出现“用户名@任何的”字样 就退出
EOF
done