1. expect
- expect
是一个免费的编程工具语言,建立在 tcl 基础上的一个工具,它可以让一些需要交互的任务自动化地完成。相当于模拟了用户和命令行的交互操作。
1.1 expect 安装及基本介绍
安装
expect 依赖于 tcl,所以需要首先安装 tcl 再安装 expect
yum install tcl -y
yum install expect -y
原理机制
- expect是自动应答命令用于交互式命令的自动执行。
- spawn是expect中的监控程序,其运行后会监控命令提出的交互问题。
- send发送问题答案给交互命令。
首先使用 spawn 开启一个会话,然后使用 expect-send 对来执行交互式操作。
spawn 后面跟上一个命令操作,表示开启一个会话。expect 等待输出特定的字符串(通常是提示符),然后使用send 发送交互字符串。比如:
编写脚本内容如下:
#!/bin/bash
/usr/bin/expect <<EOF
spawn ssh root@172.25.14.250 # 远程登录
expect {
"yes/no" { send "yes\r";exp_continue }
# 关键字为 yes/no 时,输入 yes . '\r'表示回车
# .exp_ continue标示当问题不存在时继续回答下面的问题。
"password" { send "westos\r" }
# 关键字为 password 时,输入要登录帐户的密码
}
expect eof #结束符
# .expect eof标示问题回答完毕退出expect环境。
EOF
执行如下:
1.2 expect的基本语法
1. #!/usr/bin/expect # 脚本中首先引入文件,表明使用的是哪一个shell
2. set
set timeout 30 # 设置会话超时时间为30s, 若不限制超时时间则应设置为-1
set 还可以设置变量
# 使用变量语句:$param 或者 ${param}({}用来避免 param 和后面的字符串拼接起来导致错误)
set param "param_str"
set param 1
3. spawn
spawn 后面跟一个命令,开启一个会话
spawn ${cmd} # for example : spawn ssh root@IP
4.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"}
}
5. 结束符
expect eof :等待执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了
interact : 执行完成后保持交互状态, 这时可以手动输入信息
注:expect eof 与 interact 二选一即可
6. 接收参数
参数存在argv中,使用第一个参数如下:
set param0 [lindex $argv 0]
$argc表示参数个数,判断语句如下:
if {$argc < 1} {
#do something
send_user "usage: $argv0 <param1> <param2> ... "
exit
}
注:$argv0 是脚本名,但[lindex $argv 0]是第一个参数 param1, [lindex $argv 1]
是第二个参数 param2, 以此类推
send_user 用来显示信息到父进程(一般为用户的shell)的标准输出。
示例如下:
1)编辑一个ask.sh的脚本,实现交互输出
编辑内容如下:
#!/bin/bash
read -p "What's your name: " NAME
read -p "How old are you: " AGE
read -p "How are you feel now: " FELL
echo "$NAME is $Age years old and feel $FELL now"
执行如下:
2)编辑 answer.sh 编本,实现对 ask 脚本的内容回答
#!/usr/bin/expect
spawn /tmp/shell/ask.sh
expect {
name { send "sunshine\r";exp_continue }
old { send "18\r";exp_continue }
now { send "excited\r" }
}
expect eof
执行如下(注意执行方式):
3)带参数的 answer 脚本
内容如下:
#!/usr/bin/expect
set timeout 2
set "NAME" [ lindex $argv 0 ]
set "AGE" [ lindex $argv 1 ]
set "FELL" [ lindex $argv 2 ]
spawn /tmp/shell/ask.sh
expect {
"name" { send "$NAME\r";exp_continue }
"old" { send "$AGE\r";exp_continue }
"now" { send "$FELL\r" }
}
expect eof
执行如下:
直接执行脚本,无交互内容显示
传参执行
2. 语句控制器(exit,continue,break)
exit n #脚本退出,退出值为n
break #退出当前循环
continue # 提前结束循环内部的命令,但不终止循环
例:遇到4时跳过
[root@localhost mnt]# vim num.sh
#!/bin/bash
for num in {1..10}
do
while [ "$num" -ne 4 ]
do
echo $num
break
done
done
[root@localhost mnt]# sh num.sh
执行如下: