Expect 主要应用于自动化交互式操作场景,可以将ssh、ftp、scp等需人工交互的操作写在一个脚本上使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率。
其主要交互流程是:
spawn启动指定进程 -> expect获取指定关键字 -> send发送指定指令 -> 执行完成 -> 继续或退出.
一、 下载安装
expect 是由基于Tcl( Tool Command Language )语言开发的,因此安装前需要安装tcl语言环境。可以使用yum安装或源码安装。
1. 下载
- tcl https://www.tcl.tk/software/tcltk/download84.html
- expect https://sourceforge.net/projects/expect/files/
2. yum安装
yum install -y tcl
yum install -y expect
3. 源码安装
解压安装包
tar -zxvf tcl8.4.20-src.tar.gz
tar -zxvf expect5.45.3.tar.gz
安装tcl
cd tcl8.4.20/unix/
./configure --prefix=/usr/tcl --enable-shared
make
make install
cp tclUnixPort.h ../generic
安装expect
cd /root/expect5.45.3/
./configure --prefix=/usr/expect --with-tcl=/usr/tcl/lib --with-tclinclude=/root/tcl8.4.20/generic
make
make install
ln -s /usr/tcl/bin/expect /usr/bin/expect
简单测试
[root@mydb02 ~]# expect
expect1.1> send "hello world\n"
hello world
expect1.1> expect "hi" { send "You said hi\n" } \
+> "hello" { send "Hello yourself\n" } \
+> "bye" { send "That was unexpected\n" }
#输入
hi
#输出
You said hi
二、 expect 常用命令
完整版可执行 man expect 查看
命 令 | 说 明 |
---|---|
spawn | 启动新的交互进程,后面跟命令或者指定程序 |
expect | 待匹配信息。从进程中接收信息,如果匹配成功,就执行expect后的动作 |
send | 向进程发送字符串或命令 |
send exp_send | 用于发送指定的字符串或命令 |
exp_continue | 匹配多个字符串在执行动作后加此命令 |
send_user | 打印后跟的字符串内容,相当于shell中的echo |
interact | 执行完命令后保持在交互状态,此时Expect会把控制权交给控制台,变回手工操作。如果只是登录过去执行一段命令就退出,可将其改为 expect eof |
exit | 退出expect脚本 |
eof | expect执行结束, 退出 |
set | 定义变量 |
puts | 输出变量 |
set timeout | 设置超时时间 |
三、 常用脚本
最简单的自动登录脚本
#!/usr/bin/expect
set timeout 30
spawn ssh -l root 172.16.22.131
expect "password*"
send "123456\r"
interact
# 或者 expect eof
#!/usr/bin/expect 必须位于第一行,说明需要使用系统的哪个脚本解析引擎来执行,具体路径根据实际expect 命令实际路径而定。
1. 使用变量
#!/usr/bin/expect
set ip 172.20.110.199
set user root
set password 123456wht
set timeout 10
spawn ssh $user@$ip
expect "password:"
send "$password\n"
interact
#expect eof
运行结果如下
[root@localhost ~]#./sshbl.exp
spawn ssh 172.20.110.199
[email protected]'s password:
Last login: Sat May 12 11:26:45 2018 from 172.20.110.169
[root@localhost ~]#
2. 位置参数
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh $user@$ip
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$password\n" }
}
interact
#运行 ./ssh3.exp 192.168.8.100 root magedu
3. shell脚本调用expect
批量ssh-copy-id
#!/bin/bash
#用于批量ssh-copy-id 免密码登陆服务器
which expect || yum -y install expect
TXT_PATH=/home/wht/ssh-login/list.txt
ssdzd(){
expect <<-EOF
set timeout 10
spawn ssh-copy-id $user@$ip
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$password\n" }
}
expect "]#" { send "exit\n" }
expect eof
EOF
}
a=`cat ${TXT_PATH}|wc -l`
echo $a
for i in `seq $a` ; do
echo $i
ip=`cat ${TXT_PATH}|head -n $i|tail -n 1|awk '{print $1}'`
user=`cat ${TXT_PATH}|head -n $i|tail -n 1|awk '{print $2}'`
password=`cat ${TXT_PATH}|head -n $i|tail -n 1|awk '{print $3}'`
ssdzd
done
list.txt
- 192.168.8.27 root zmoam#11232134
- 192.168.8.31 root zmoam#11231234
6. 自动mv文件
vi exe.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "xxxx"
spawn ssh myuser@$host
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$passwd\n" }
}
expect "$ "
send "sudo -i\r"
expect "myuser:"
send "$passwd\r"
expect "]# "
send "cd /etc/zabbix/zabbix_agentd.d/zabora/sql\r"
expect "]# "
send "mv test.txt test.txt.bak\r"
expect "]# "
send "exit\r"
#expect eof
expect "~]$ "
send "exit\r"
expect eof
vi test.sh
#!/bin/bash
for ip in `cat ip.txt`
do
./exe.expect $ip
done
ip.txt
- 192.168.3.225
- 192.168.3.247
执行效果
[root@mydb02 ~]# ./test.sh ip.txt
spawn ssh [email protected]
[email protected]'s password:
Last login: Wed Dec 2 19:07:49 2020 from 10.13.3.224
[myuser@mydb03 ~]$ sudo -i
[sudo] password for myuser:
[root@mydb03 ~]# cd /etc/zabbix/zabbix_agentd.d/zabora/sql
[root@mydb03 sql]# mv test.txt test.txt.bak
[root@mydb03 sql]# exit
logout
[myuser@mydb03 ~]$ exit
logout
Connection to 192.168.3.225 closed.
spawn ssh [email protected]
[email protected]'s password:
Last login: Wed Dec 2 19:07:50 2020 from 10.13.3.224
[myuser@mydb04 ~]$ sudo -i
[sudo] password for myuser:
[root@mydb04 ~]# cd /etc/zabbix/zabbix_agentd.d/zabora/sql
[root@mydb04 sql]# mv test.txt test.txt.bak
[root@mydb04 sql]# exit
logout
[myuser@mydb04 ~]$ exit
logout
Connection to 192.168.3.247 closed.
[root@mydb02 ~]#
参考
http://blog.leanote.com/post/[email protected]/shell%E7%BC%96%E7%A8%8B%E4%B9%8Bexpect
https://www.linuxprobe.com/linux-expect-auto.html
https://www.cnblogs.com/gylei/archive/2013/05/11/3072331.html