首先简单介绍一下expect:
expect基于Tcl语言开发,主要应用于自动化交互式操作场合,借助Expect处理交互的命令,可以将交互 过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完。
expect语法:expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
expect中常用命令:
- spawn:启动新的进程
- send:用于向进程发送字符串
- expect:从进程接收字符串
- interact:允许用户交互
- exp_continue:追加命令
expect默认自动交互,如果需要人工交互,需要用interact。
expect默认未安装,需要执行yum install -y expect
安装,此包依赖于Tcl,所以也会附带安装Tcl。
在终端输入expect可开启一个交互式会话:
单分支模式:
接收到expect后面添加的内容后,就自动发送send后的内容。
多分支模式1:
多分支模式2:
默认没有换行,需要自己添加到send中。
好了,看实际的例子:
需求:能在10台机器上批量执行某个脚本。
需求拆分:批量执行脚本需要需要将脚本复制到客户端,需要用到scp;而执行则需要登录到客户端,可用ssh。
可分成三个文件:
新建一个名为ip的文件,其中存放ip地址,便于管理。我这里就两台主机,所以这里就写了两行,如下:
192.168.10.10 root root
192.168.10.11 root rootyy
总共用到了三个文件:
- 一个ip,如上所示,存放客户端的ip、用户名、密码;
- 一个scripts.sh,要复制到目标主机的脚本文件(记得这边先添加好执行权限),
- 另外一个就是具体跑的脚本auto_sc.sh了。
依次贴出代码:
#!/bin/bash
cd /var/
touch test_expect
echo "it works!" > test_expect
#!/bin/bash
func(){
ip=$1 #接收IP的变量
user=$2 #接收用户名的变量
password=$3 #接收密码的变量
echo $ip
echo $user
echo $password
expect <<EOF
set timeout 10
spawn scp /root/bin/scripts.sh $user@$ip:/var/
expect {
"yes/no" {send "yes\n";exp_continue}
"password" {send "$password\n"}
}
expect eof
spawn ssh $user@$ip
expect {
"yes/no" {send "yes\n";exp_continue}
"password" {send "$password\n"}
}
expect "]#" {send "cd /var\n"}
expect "]#" {send "./scripts.sh\n"}
send "exit\n"
expect eof
EOF
}
while read line;do
IP=${line%% *}
USER=`echo $line |cut -d' ' -f2`
PAWD=${line##* }
func $IP $USER $PAWD
done < ./ip
注:我这里是直接在脚本中调用expect,expect也可以单独写,它有自己的语法,文件后缀为.exp,首行为#!/usr/bin/expect
贴执行成功的结果:
复制的文件有了:
创建的文件也有了:
这里只做一个Demo,复杂应用自己结合实际用吧。