0. 简介
expect
是建立在tcl
(参见:Tcl/Tk快速入门 )基础上的一个工具,它可以让一些需要交互的任务自动化地完成。相当于模拟了用户和命令行的交互操作。
一个具体的场景: 远程登陆服务器,并执行命令
登录时输入密码需要交互,bash脚本无法完成,可以使用expect来完成。
1. 安装
yum 安装
yum install -y expect
2. 原理与工作机制
首先使用 spawn
开启一个会话,然后使用 expect-send
对来执行交互式操作。
spawn
后面跟上一个命令操作,表示开启一个会话。expect 等待输出特定的字符串(通常是提示符),然后使用send 发送交互字符串。比如:
# 远程登录
spawn ssh username@host
# 提示为:"username@host's password:", 等待用户输入密码
expect "*assword"
# 这时使用send模拟用户输入密码的字符串,完成登录验证
send "${password}\r"
3. 基本语法介绍
脚本解释器
脚本中首先引入文件,表明使用的是哪一个shell
#!/usr/bin/expect
set
设置会话超时时间为30s, 若不限制超时时间则应设置为-1
set timeout 30
set 还可以设置变量
# 使用变量语句:$param 或者 ${param}({}用来避免param和后面的字符串拼接起来导致错误)
set param "param_str"
set param 1
spawn
spawn 后面跟一个命令,开启一个会话
# for example : spawn su root
spawn ${cmd}
expect - send
expect 接收命令执行后的输出,然后和期望字符串匹配,若对应这执行相应的send来发送交互信息。
# 这一行等同于下面两行
expect "$case1" {send "$respond1\r"}
expect "$case1"
send "$response1\r"
expect 可以有多个分支,就像switch语句一样。
expect
{
"$case1" {send "$response1\r"}
"$case2" {send "$response2\r"}
"$case3" {send "$response3\r"}
}
结束符
expect eof
:等待执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了
interact
: 执行完成后保持交互状态, 这时可以手动输入信息
注:
expect eof 与 interact 二选一即可
4. 实例
实现远程登录服务器,并切换到root用户下执行关闭防火墙的命令,然后退出。
#!/usr/bin/expect
if {$argc < 4} {
#do something
send_user "usage: $argv0 <remote_user> <remote_host> <remote_pwd> <remote_root_pwd>"
exit
}
set timeout -1
set remote_user [lindex $argv 0] # 远程服务器用户名
set remote_host [lindex $argv 1] # 远程服务器域名
set remote_pwd [lindex $argv 2] # 远程服务器密码
set remote_root_pwd [lindex $argv 3] # 远程服务器根用户密码
# 远程登录
spawn ssh ${remote_user}@${remote_host}
expect "*assword:" {send "${remote_pwd}\r"}
expect "Last login:"
# 切换到 root
send "su\r"
expect "*assword:" {send "${remote_root_pwd}\r"}
# 执行关闭防火墙命令
send "service iptables stop\r"
send "exit\r"
send "exit\r"
expect eof