1. expect
expect是一个免费的,建立在tcl基础上的编程工具,它可以让一些需要交互的任务自动化的完成,相当于模拟了用户与命令行之间的交互操作。
通过shell可以实现简单的控制流功能,如:判断,循环等。但是对于需要交互的场合就必须通过人工干预,所以我们需要expect工具来实现和交互程序,如telnet服务器的交互功能。
1.1 expect安装及介绍
expect 依赖于tcl,所以需要先安装tcl在安装expect。
yum install expect -y
yum install tcl -y
原理机制:
expect是自动应答执行用于交互式任务的命令。 spawn是expect中的监控程序,其运行后会监控命令提出的交互问题。
send发送问题答案给交互命令。 先使用spawn开启一个会话,然后使用expect-send对来执行交互式操作。
spawn后面跟上一个命令操作,表示开启一个会话。expect等待输出特定的字符串(通常是提示符),然后使用send发送交互字符串。
#!/bin/bash
/usr/bin/expect <<EOF
spawn ssh root@172.25.254.61 # 远程登录
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.3 示例:
编辑脚本info.sh实现交互输出:
#!/bin/bash
read -p "What's your name: " NAME
read -p "How old are you: " AGE
read -p "Where are you from: " PLACE
echo "$NAME is $AGE years old and she comes from $PLACE."
编写应答脚本,answer.sh
#!/usr/bin/expect
spawn /root/Desktop/info.sh #交互式脚本所在路径
expect {
"name" { send "monster\r";exp_continue }
"old" { send "18\r";exp_continue }
"Where" { send "shannxi\r" } #关键词匹配是区分大小写的
}
expect eof
执行方式如下:
1.4 带参数的answer脚本
#!/usr/bin/expect
set timeout 2
set "NAME" [ lindex $argv 0 ]
set "AGE" [ lindex $argv 1 ]
set "PLACE" [ lindex $argv 2 ]
spawn /root/Desktop/info.sh
expect {
"name" { send "$NAME\r";exp_continue }
"old" { send "$AGE\r";exp_continue }
"Where" { send "$PLACE\r" }
}
expect eof
传参执行:
也可以将其封装为一个函数: