Linux系统shell脚本(五)
一、Expect 脚本
xpect 是一个免费的编程工具语言,能实现自动和交互式任务通信,无需人工干预。它由 Don Libes 于 1990 年开始编写,可对需要从终端获取输入的命令或程序提供模拟输入,甚至能实现简单的 BBS 聊天机器人。
Shell 虽能实现循环、判断等简单控制流功能,但在交互场合需人工干预。而 Expect 可解决如 SSH、FTP 服务器免交互自动连接等问题,不过它需要 Tcl 编程语言的支持,运行前需先安装 Tcl。
[root@localhost ~]# yum install -y expect
#安装 expect
[root@localhost ~]# yum install -y tcl
#安装 tcl
通过 ssh 远程操控主机时,解决交互的方式有:
- 通过 ssh 的密钥对
- 通过 sshpass 工具提交密码
- 通过 expect 工具提交密码
二、安装 expect
[root@localhost ~]# yum install -y tcl
#安装tcl
[root@localhost ~]# yum install -y expect
#安装expect
三、如何使用 expect
expect 常规使用的工作流程为:spawn 启动指定进程→expect 获取期待的关键字→send 向指定进程发送响应内容→进程执行完成后,退出 expect 程序。下面介绍其关键部分:
三、如何使用 expect
expect 常规使用的工作流程为:spawn 启动指定进程→expect 获取期待的关键字→send 向指定进程发送响应内容→进程执行完成后,退出 expect 程序。下面介绍其关键部分:
3-1、spawn 命令
作用是启动新的产生交互的进程,语法为:
spawn [选项] [需要执行的shell命令或程序等]
例如修改已存在账户密码时,可使用spawn passwd tom
启动 passwd 进程。
3-2、expect 命令
用于获取 spawn 执行命令或程序后产生的交互信息,判断是否匹配,匹配则执行相应动作,语法为:
expect [选项] 表达式 [动作]
选项如 “-re” 表示使用正则表达式匹配。
3-3、send 命令
在 expect 命令匹配指定字符后,向系统程序发送指定字符串,支持 n(回车)、r(换行)、t(制表符)等特殊转义符。
案例 :修改密码
#!/usr/bin/expect
spawn passwd tom
expect {
"*密码:" { send "123.com"; exp_continue }
"*新的密码:" { send "123.com" }
eof
}
案例:
3-4、exp_continue 命令
若需一次匹配多个字符串并执行不同动作,该命令可让 expect 程序继续匹配。
3-5、send_user 命令
用于打印 expect 脚本信息,类似 shell 里的 echo 命令,例如:
[root@localhost ~]# vim send_user.exp
#!/usr/bin/expect
#Filename: send_user.exp
send_user "beijingn"
send_user "shanghait"
send_user "guangzhoun"
3-6、expect 变量
- 普通变量:定义语法为
set 变量名 变量值
,调取方式为puts $变量名
或send_user "$变量名"
。 - 位置参数变量:通过
set <变量名称> [lindex $argv <param index> ]
接收,$argc
表示传入参数个数,$argv0
表示当前执行脚本的名称。
四、Shell 脚本调用 expect 的方法
在shell脚本中使用/usr/bin/expect <<-EOF ... EOF的方式可以调用绝大多数的其它脚本语言,这种方式执行命令建议使用绝对路径,而且要严格遵守expect 的脚本格式;
[root@localhost ~]# cat shell-expect2.sh#!/bin/bashfor i in 192.168.200.{112..113}do/usr/bin/expect << EOFspawn ssh root@$i ifconfig ens32expect {"yes/no" { send "yes\\r";exp_continue }"password" { send "123456\n" }}expect eofEOFdone
案例:通过shh服务输出两台主机IP信息
#!/bin/bash
for i in 192.168.246.133 192.168.246.137
do
expect <<EOF
spawn ssh root@$i ip a
expect {
"*yes/no*" { send "yse\r"; exp_continue }
"*password: " { send "q1w2e3@123!!!!!\r";exp_continue }
}
EOF
done
案例:批量更改密码
#创建密码本
vim mm.txt
user1:123456
user2:123456
user3:123456
user4:123456
user5:123456
#脚本
vim change_passwd.sh
#!/bin/bash
#批量更改用户密码
user=$(cat user_passwd.txt | cut -d ':' -f1)
passwd=$(cat user_passwd.txt | cut -d ':' -f2)for i in $user
doexpect<<EOFspawn passwd $iexpect {"*密码:" { send "$passwd\r"; exp_continue }"*密码:" { send "$passwd\r"; }}EOF