1. 分发系统介绍
如今一些比较大的企业,大都使用了负载均衡,而有时因为一些程序要更改,或者有些bug要修改,快速更新代码等,如果仅是几台server的话,很简单,把已经改好的程序拷过去,或者rsync远程推送,再或者网上NFS共享一下就可以了;但如果有几十台几百台,那样的方法会太繁琐,此时就可以用expect来批量实现分发任务。
-
expect:一个实现自动交互功能的软件套件,基于Tcl的一种脚本语言,具有简单的语法;
-
功能:实现自动登录远程机器,并自动执行命令;和shell脚本结合,可以实现完全自动化;
-
注意:若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令。但当不能使用密钥验证的时候,我们就没有办法了。所以,这时只知道对方机器的账号和密码可以通过expect脚本实现登录和远程命令。
2. expect 脚本设置
在之前我们已经学习过一个命令mkpasswd,在使用这个命令的时候需要安装expect,同样在这我们也需要安装expect。
yum install -y expect
2.1 expect脚本登录远程机器
2.1.1 创建远程登陆脚本
[root@linux-01 ~]# cd /usr/local/sbin/
[root@linux-01 sbin]# mkdir expect
[root@linux-01 sbin]# cd expect/
[root@linux-01 expect]# vim load.expect
#!/usr/bin/expect
# 设置远程登录主机IP #
set host "192.168.241.89"
# 设置远程主机登录密码 #
set passwd "123qwe"
# 设置执行命令 #
spawn ssh root@$host
expect {
#第一次登陆,需要yse,然后回车,继续执行 #
"yes/no" { send "yes\r"; exp_continue}
# 输入密码 #
"password:" { send "$passwd\r" }
}
# 命令执行完之后,呆在远程主机 #
interact
-
代码解释: #! /usr/bin/expect 这一行告诉操作系统脚本里的代码使用那一个shell来执行。
-
在expect下 定义变量,用 set,比如 定义变量a为1 :set a 1
-
expect 使用expect语句进行交互
-
\r表示回车
-
exp_continue 表示继续 \r 表示换行 interact 继续停留在这台机器,不退出。
-
interact表示继续交互
2.1.2 测试脚本
[root@linux-01 expect]# chmod a+x load.expect
[root@linux-01 expect]# ./load.expect
spawn ssh root@192.168.241.89
root@192.168.241.89's password:
Last login: Wed Jun 19 22:41:09 2019 from 192.168.241.1
welcome to linux!
[root@linux-02 ~]# logout
Connection to 192.168.241.89 closed.
[root@linux-01 expect]#
2.2 远程登录执行命令
2.2.1 创建脚本
[root@linux-01 expect]# vim load1.expect
#!/usr/bin/expect
set user "root"
set passwd "123qwe"
spawn ssh $user@192.168.241.89
expect {
"yes/no" { send "yes\r"; exp_continue}
"password:" { send "$passwd\r" }
}
expect "]*"
send "touch /tmp/12.txt\r"
expect "]*"
send "echo 1212 > /tmp/12.txt\r"
expect "]*"
send "exit\r"
2.2.1 测试脚本
[root@linux-01 expect]# chmod a+x load1.expect
[root@linux-01 expect]# ./load1.expect
spawn ssh root@192.168.241.89
root@192.168.241.89's password:
Last failed login: Wed Jun 19 23:07:18 CST 2019 from 192.168.241.88 on ssh:notty
There were 5 failed login attempts since the last successful login.
Last login: Wed Jun 19 22:59:21 2019 from 192.168.241.88
welcome to linux!
[root@linux-02 ~]# touch /tmp/12.txt
[root@linux-02 ~]# echo 1212 > /tmp/12.txt
[root@linux-02 ~]# [root@linux-01 expect]#
2.3 expect脚本传递参数
2.3.1 创建脚本
[root@linux-01 expect]# vim load2.expect
#!/usr/bin/expect
set user [lindex $argv 0]
set host [lindex $argv 1]
set passwd "123qwe"
set cm [lindex $argv 2]
spawn ssh $user@$host
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"
2.3.2 测试脚本
[root@linux-01 expect]# chmod 755 load2.expect
[root@linux-01 expect]# ./load2.expect root 192.168.241.89 ls
spawn ssh root@192.168.241.89
root@192.168.241.89's password:
Last failed login: Wed Jun 19 23:33:18 CST 2019 from 192.168.241.88 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Wed Jun 19 23:31:45 2019 from 192.168.241.1
welcome to linux!
[root@linux-02 ~]# ls
anaconda-ks.cfg rsync wenjian.txt
[root@linux-02 ~]# [root@linux-01 expect]#
2.4 expect脚本同步文件
2.4.1 设置脚本
-
expect eof 语句解释:
-
spawn执行的命令结果,会被expect捕捉到。因为spawn会启动一个进程,只有这个进程的相关信息才会被捕捉到,主要包括:标准输入的提示信息,eof和timeout。
-
在这里eof是必须去匹配的,在spawn进程结束后会向expect发送eof,如果expect没有匹配,那么会立即退出远程登录,即操作失败。
[root@linux-01 expect]# vim load3.expect
#!/usr/bin/expect
set passwd "123wqe"
spawn rsync -av root@192.168.241.89:/tmp/12.txt /tmp/
expect {
"yes/no" { send "yes\r"}
"password:" { send $passwd\r}
}
expect eof
2.4.2 测试结果
[root@linux-01 expect]# chmod a+x load3.expect
[root@linux-01 expect]# ./load3.expect
spawn rsync -av root@192.168.241.89:/tmp/12.txt /tmp/
root@192.168.112.138's password:
receiving incremental file list
12.txt
sent 43 bytes received 97 bytes 93.33 bytes/sec
total size is 5 speedup is 0.04
2.5 expect脚本指定参数
2.5.1 设置脚本
[root@linux-01 expect]# vim load4.expect
#!/usr/bin/expect
set passwd "123qwe"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -av $file root@$host:$file
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r"}
}
expect eof
2.5.2 测试脚本
- 注意:
- 这里要同步的文件,必要要写绝对路径;
- 备份的时候,注意时间限制;可以设定 set timeout 定义超时时间(单位为 秒) -1 为永远不超时。
[root@ying01 sbin]# chmod a+x load4.expect
[root@ying01 sbin]# ./load4.expect 192.168.241.89 "/tmp/12.txt"
spawn rsync -av /tmp/12.txt root@192.168.241.89:/tmp/12.txt
root@192.168.241.89's password:
sending incremental file list
sent 45 bytes received 12 bytes 114.00 bytes/sec
total size is 5 speedup is 0.09
3. 构建文件分发系统
-
需求背景:对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。
-
实现思路:首先要有一台模板机器,把要分发的文件准备好,然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可。
-
核心命令:rsync -av --files-from=list.txt / root@host:/ 注意:这里的都是根目录(使用rsync 的 --files参数,可以实现调用文件里面的列表,进行多个文件远程传输,进而实现文件分发文件分发系统的实现。)
3.1 编写登录远程服务器执行命令的脚本
[root@linux-01 expect]# vim rsync.expect
#!/usr/bin/expect
set passwd "123qwe"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -avR --files-from=$file / root@$host:/
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof
3.2 定义远程登录服务器的一个list
[root@linux-01 expect]# vim /tmp/ip.list
192.168.241.89
127.0.0.1
3.3 定义同步的列表
[root@linux-01 expect]# vim /tmp/file.list
/tmp/12.txt
/root/NBA
/root/grep/221.txt
3.4 创建一个shell脚本
[root@linux-01 expect]# vim rsync.sh
#!/bin/bash
for ip in `cat /tmp/ip.list`
do
./rsync.expect $i /tmp/file.list
done
3.5 测试结果
[root@linux-01 expect]# chmod a+x rsync.expect
[root@linux-01 expect]# sh -x rsync.sh /
++ cat /tmp/ip.list
+ for i in '`cat /tmp/ip.list`'
+ ./rsync.expect 192.168.241.89 /tmp/file.list
spawn rsync -avR --files-from=/tmp/file.list / root@192.168.241.89:/
root@192.168.241.89's password:
building file list ... done
root/
root/221.txt
root/NBA/
root/grep/
sent 6,860 bytes received 44 bytes 13,808.00 bytes/sec
total size is 6,625 speedup is 0.96
+ for i in '`cat /tmp/ip.list`'
+ ./rsync.expect 127.0.0.1 /tmp/file.list
spawn rsync -avR --files-from=/tmp/file.list / root@127.0.0.1:/
root@127.0.0.1's password:
building file list ... done
root/
root/221.txt
root/NBA/
root/grep/
tmp/
sent 6,863 bytes received 47 bytes 13,820.00 bytes/sec
total size is 6,625 speedup is 0.96
4. 批量远程执行命令
4.1 设置批量执行命令的脚本
[root@linux-01 expect]# vim exe.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "123qwe"
set cm [lindex $argv 1]
spawn ssh root@$host
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"
4.2 设置shell脚本
[root@linux-01 expect]# vim exe.sh
#!/bin/bash
for ip in `cat ip.list`
do
echo $ip
./exe.expect $ip "w;free -m;ls /tmp"
done
4.3 测试结果
[root@linux-01 expect]# chmod 755 exe.expect
[root@linux-01 expect]# sh -x exe.sh
++ cat ip.list
+ for ip in '`cat ip.list`'
+ echo 192.168.241.89
192.168.241.89
+ ./exe.expect 192.168.241.89 'w;free -m;ls /tmp'
spawn ssh root@192.168.241.89
root@192.168.241.89's password:
Last failed login: Wed Jun 19 23:40:48 CST 2019 from 192.168.241.88 on ssh:notty
There were 7 failed login attempts since the last successful login.
Last login: Wed Jun 19 23:35:17 2019 from 192.168.241.88
welcome to linux!
[root@linux-02 ~]# w;free -m;ls /tmp
00:56:06 up 1:25, 2 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.241.1 23:31 1:24m 0.07s 0.07s -bash
root pts/1 192.168.241.88 00:56 0.00s 0.05s 0.01s w
total used free shared buff/cache available
Mem: 1819 184 1413 9 221 1441
Swap: 3813 0 3813
12.txt systemd-private-defba3fc9432428d98d304a0fe8a9758-chronyd.service-mTFzBl systemd-private-defba3fc9432428d98d304a0fe8a9758-cups.service-AyJcYR
[root@linux-02 ~]# + for ip in '`cat ip.list`'
+ echo 127.0.0.1
127.0.0.1
+ ./exe.expect 127.0.0.1 'w;free -m;ls /tmp'
spawn ssh root@127.0.0.1
root@127.0.0.1's password:
Last failed login: Thu Jun 20 00:56:19 CST 2019 from localhost on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Wed Jun 19 23:31:46 2019 from 192.168.241.1
welcome to linux!
[root@linux-01 expect]# w;free -m;ls /tmp
00:58:14 up 1:27, 1 user, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.241.1 23:31 6.00s 0.30s 0.04s w
total used free shared buff/cache available
Mem: 1819 178 1410 9 230 1447
Swap: 3813 0 3813
mysql.sock systemd-private-96bf4487d1f441d59219eaebecda084a-cups.service-BNZAMB yum_save_tx.2019-06-10.23-22.fpfJYt.yumtx
systemd-private-2135bfb0630d425ba47913f1a2d6fed6-chronyd.service-53rgm2 systemd-private-96bf4487d1f441d59219eaebecda084a-httpd.service-LiuDev yum_save_tx.2019-06-10.23-29.5cxOm7.yumtx
systemd-private-2135bfb0630d425ba47913f1a2d6fed6-cups.service-9om5r8 vmware-root_6205-1992172553
systemd-private-96bf4487d1f441d59219eaebecda084a-chronyd.service-3fkCSI vmware-root_6222-734562333
[root@linux-01 expect]#