一、介绍
expect是一款自动化的脚本解释型的工具。
expect基于tcl脚本,expect脚本的运行需要tcl的支持。
expect对一些需要交互输入的命令很有帮助,比如ssh ftp scp telnet。
远程登录linux服务器的时候,ssh命令需要手工输入密码,当登录多台机器的时候就会非常繁琐。
expect就可以根据设定的规则,自动帮我们输入密码,大大节省了时间。
二、安装expect
一般机器不会自带expect,需要手动安装。yum源安装expect,使用yum源可以自动解决依赖,也可以rpm包安装
# yum install expect -y # expect expect1.1>
三、expect基础知识
expect脚本
脚本开头
expect脚本一般以#!/usr/bin/expect -f开头,类似bash脚本。
常用后缀
expect脚本常常以.exp或者.ex结束。
expect主要命令
spawn 新建一个进程,这个进程的交互由expect控制
expect 等待接受进程返回的字符串,直到超时时间,根据规则决定下一步操作
send 发送字符串给expect控制的进程
set 设定变量为某个值
exp_continue 重新执行expect命令分支
[lindex $argv 0] 获取expect脚本的第1个参数
[lindex $argv 1] 获取expect脚本的第2个参数
set timeout -1 设置超时方式为永远等待
set timeout 30 设置超时时间为30秒
interact 将脚本的控制权交给用户,用户可继续输入命令
expect eof 等待spawn进程结束后退出信号eof
expect命令分支
expect命令采用了tcl的模式-动作语法,此语法有以下几种模式:
单一分支语法
set password 123456
expect "*assword:" { send "$password
" }
当输出中匹配*assword:时,输出password变量的数值和回车。
多分支语法
set password 123456
expect {
"(yes/no)?" { send "yes
"; exp_continue }
"*assword:" { send "$password
" }
}
当输出中包含(yes/no)?时,输出yes和回车,同时重新执行此多分支语句。
当输出中匹配*assword:时,输出password变量的数值和回车。
四、expect应用实例
1.传参式ssh登录指定主机
#!/usr/bin/expect -f set ip [ lindex $argv 0 ] //接收第一个参数,并设置IP set pass [ lindex $argv 1 ] //接收第二个参数,并设置密码 set timeout 10 //设置超时时间 spawn ssh root@$ip //发送ssh请求 expect { //返回信息匹配 "*yes/no" { send "yes "; exp_continue} //第一次ssh连接会提示yes/no,自动发送yes "*password:" { send "$pass " } //出现密码提示,发送密码 } interact //交互模式,用户会停留在远程服务器上面
2.利用expect批量ssh互信
编写hosts文本用于存放主机信息
#!/bin/bash # 判断id_rsa密钥文件是否存在 if [ ! -f ~/.ssh/id_rsa ];then ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa else echo "id_rsa has created ..." fi #分发到各个节点,这里分发到host文件中的主机中. while read line do user=`echo $line | cut -d " " -f 2` ip=`echo $line | cut -d " " -f 1` passwd=`echo $line | cut -d " " -f 3` expect <<EOF set timeout 10 spawn ssh-copy-id $user@$ip expect { "yes/no" { send "yes ";exp_continue } "password" { send "$passwd " } } expect "password" { send "$passwd " } EOF done < hosts