目录
一、分发系统介绍
二、expect脚本远程登录
三、expect脚本远程执行命令
四、expect脚本传递参数
五、expect脚本同步文件
六、expect脚本指定host和要同步的文件
七、构建文件分发系统
八、批量远程执行命令
一、分发系统介绍
-
场景:
服务器是LAMP或LNMP环境,运行PHP网站业务。随着业务增长,代码不断迭代,有增加新功能的需求,需要修改代码,但提供服务的机器数量庞大,逐一更新服务器上的代码比较困难。 -
分发系统介绍
分发系统的作用是将每段时间更新的代码分别发到服务机器上去,这里使用shell编程脚本实现代码上线(将代码发布到线上环境)。部分开源软件系统也可以实现发布代码到服务器的功能。 -
上线准备工作及过程
准备一台模板机器,该机器上的代码是更新后需要上线的代码,使用expect脚本,借助rsync将更新的代码推送到需要上线的机器上。如果需要执行一些命令,可以借助expect登录机器执行命令。
二、expect脚本远程登录
expect是一种能够按照脚本内容里面设定的方式与交互式程序进行“会话”的程序。expect可以知道程序会提示或反馈什么内容以及什么是正确的应答。它是一种可以提供“分支和嵌套结构”来引导程序流程的解释型脚本语言。另外,还可以在随时需要的时候把控制权交给用户,然后再还给脚本。
- 安装expect
#若未安装则使用yum安装
[root@minglinux-01 ~] yum install -y expect
- expect实现远程登录脚本
[root@minglinux-01 /usr/local/sbin] vim 1.expect
1 #!/usr/bin/expect
2 set host "192.168.162.132" #set 变量名 定义变量
3 set passwd "123456" #
4 spawn ssh root@$host #
5 expect { #用户交互
6 "yes/no"{ send "yes\r";exp_continue } #截取输出内容,当输出的内容包含yes/no时,发送yes并回车(初次登录时的情景),\r表示回车,exp_continue表示继续
7 "password: " { send "$passwd\r" } #继续发送密码
8 }
9 interact #Interact表示停留在远程机器上等待交互不退出
#expect eof则会在远程机器上停留一两秒后再退出
#不加第九行interact会马上退出远程机器
- 测试expect脚本
[root@minglinux-01 /usr/local/sbin] chmod a+x 1.expect #增加权限
#清除内容恢复"yes/no"提示
[root@minglinux-01 /usr/local/sbin] vim /root/.ssh/known_hosts
[root@minglinux-01 /usr/local/sbin] ./1.expect
spawn ssh root@192.168.162.132
The authenticity of host '192.168.162.132 (192.168.162.132)' can't be established.
ECDSA key fingerprint is SHA256:iqL2TD9uuoPLw0iBc4CDeg2rwceB4m5w79eFoE94zWo.
ECDSA key fingerprint is MD5:5b:95:6c:f7:1b:4d:84:5e:66:0d:b1:fa:a7:e2:4e:d6.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.162.132' (ECDSA) to the list of known hosts.
root@192.168.162.132's password:
Last login: Mon Jan 14 17:16:31 2019 from 192.168.162.130
[root@minglinux-02 ~]
三、expect脚本远程执行命令
#minglinux-01上执行
[root@minglinux-01 /usr/local/sbin] vim 2.expect
1 #!/usr/bin/expect
2 set user "root"
3 set passwd "123456"
4 spawn ssh $user@192.168.162.132
5
6 expect {
7 "yes/no" { send "yes\r"; exp_continue}
8 "password:" { send "$passwd\r" }
9 }
10 expect "]*" #当匹配到"]*"字符时执行以下命令,"*"表通配
11 send "touch /tmp/expect.txt\r"
12 expect "]*"
13 send "echo hellohello > /tmp/expect.txt\r"
14 expect "]*"
15 send "exit\r" #直接退出远程机器
[root@minglinux-01 /usr/local/sbin] chmod a+x 2.expect
[root@minglinux-01 /usr/local/sbin] ./2.expect
spawn ssh root@192.168.162.132
root@192.168.162.132's password:
Last login: Mon Jan 14 21:39:24 2019 from 192.168.162.1
[root@minglinux-02 ~] touch /tmp/expect.txt
[root@minglinux-02 ~] echo hellohello > /tmp/expect.txt
##minglinux-02上执行
[root@minglinux-02 /tmp] cat expect.txt
hellohello
四、expect脚本传递参数
[root@minglinux-01 /usr/local/sbin] vim 3.expect
1 #!/usr/bin/expect
2
3 set user [lindex $argv 0] #将第一个参数传递给变量user
4 set host [lindex $argv 1] #将第二个参数传递给变量host
5 set passwd "123456"
6 set cm [lindex $argv 2] #将第三个变量传递给cm
7 spawn ssh $user@$host
8
9 expect {
10 "yes/no" { send "yes\r"}
11 "password:" { send "$passwd\r" }
12 }
13 expect "]*"
14 send "$cm\r"
15 expect "]*"
16 send "exit\r"
#执行3.expect
[root@minglinux-01 /usr/local/sbin] chmod a+x 3.expect
[root@minglinux-01 /usr/local/sbin] ./3.expect root 192.168.162.132 ls
spawn ssh root@192.168.162.132
root@192.168.162.132's password:
Last login: Mon Jan 14 22:02:12 2019 from 192.168.162.130
[root@minglinux-02 ~] ls
anaconda-ks.cfg SIMLI.TTF
a.txt zabbix-release-3.2-1.el7.noarch.rpm
jdk-8u191-linux-x64.tar.gz
#执行多个命令
[root@minglinux-01 /usr/local/sbin] ./3.expect root 192.168.162.132 "ls;w;vmstat 1"
spawn ssh root@192.168.162.132
root@192.168.162.132's password:
Last login: Mon Jan 14 22:25:19 2019 from 192.168.162.130
[root@minglinux-02 ~] ls;w;vmstat 1
anaconda-ks.cfg SIMLI.TTF
a.txt zabbix-release-3.2-1.el7.noarch.rpm
jdk-8u191-linux-x64.tar.gz
22:28:07 up 1 day, 18:09, 4 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.162.1 15:58 5:20m 0.03s 0.03s -bash
root pts/1 192.168.162.1 21:39 21:11 0.04s 0.04s -bash
root pts/2 192.168.162.130 17:19 5:09m 0.02s 0.02s -bash
root pts/3 192.168.162.130 22:28 0.00s 0.02s 0.02s w
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 592460 2076 664988 0 0 1 11 52 54 0 0 100 0 0
0 0 0 592528 2076 665060 0 0 0 0 99 93 0 0 100 0 0
0 0 0 592528 2076 665060 0 0 0 0 88 84 0 0 100 0 0
0 0 0 592528 2076 665060 0 0 0 0 119 111 0 0 100 0 0
0 0 0 592528 2076 665060 0 0 0 0 99 91 0 0 100 0 0
0 0 0 592528 2076 665060 0 0 0 0 98 88 0 1 100 0 0
0 0 0 592528 2076 665060 0 0 0 0 113 99 0 0 100 0 0
0 0 0 592528 2076 665060 0 0 0 0 98 93 0 1 100 0 0
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 592528 2076 665060 0 0 0 0 89 83 0 0 100 0 0
0 0 0 592528 2076 665060 0 0 0 0 100 96 0 0 100 0 0
##在expect中存在超时时间(大约10s),不适合运行需要长时间执行的命令如vmstat
五、expect脚本同步文件
[root@minglinux-01 /usr/local/sbin] vim 4.expect
1 #!/usr/bin/expect
2 set passwd "123456"
3 spawn rsync -av root@192.168.162.132:/tmp/expect.txt /tmp/
4 expect {
5 "yes/no" { send "yes\r"}
6 "password:" { send "$passwd\r" }
7 }
8 expect eof #若无expect eof则rsync还未来得及传输文件就被退出终端
#使用set timeout设置超时时间,
#如set timeout 5设置超时时间为5s,
#set timeout -1设置超时时间为永不超时。
[root@minglinux-01 /usr/local/sbin] chmod a+x 4.expect
[root@minglinux-01 /usr/local/sbin] ./4.expect
spawn rsync -av root@192.168.162.132:/tmp/expect.txt /tmp/
root@192.168.162.132's password:
receiving incremental file list
expect.txt
sent 43 bytes received 106 bytes 99.33 bytes/sec
total size is 11 speedup is 0.07
[root@minglinux-01 /usr/local/sbin] ls /tmp/expect.txt
/tmp/expect.txt
六、expect脚本指定host和要同步的文件
#从本机同步到对方
[root@minglinux-01 /usr/local/sbin] vim 5.expect
#脚本内容,此方式只能同步一个文件或者目录
1 #!/usr/bin/expect
2 set passwd "123456"
3 set host [lindex $argv 0]
4 set file [lindex $argv 1]
5 spawn rsync -av $file root@$host:$file
6 expect {
7 "yes/no" { send "yes\r"}
8 "password:" { send "$passwd\r" }
9 }
10 expect eof
[root@minglinux-01 /usr/local/sbin] chmod a+x 5.expect
[root@minglinux-01 /usr/local/sbin] ./5.expect 192.168.162.132 "/tmp/expect.txt"
spawn rsync -av /tmp/expect.txt root@192.168.162.132:/tmp/expect.txt
root@192.168.162.132's password:
sending incremental file list
sent 48 bytes received 12 bytes 120.00 bytes/sec
total size is 11 speedup is 0.18
七、构建文件分发系统
- 需求背景:
对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。 - 思路:
需要有一台模板机器,准备好要分发的文件,使用expect脚本批量将需要同步的文件分发到目标机器。 - 核心命令:
rsync -av –files-from=list.txt / root@host:/
#用于同步文件的rsync.expect 脚本文件内容
[root@minglinux-01 /usr/local/sbin] vim rsync.expect
1 #!/usr/bin/expect
2 set passwd "123456" #考虑安全性可使用密钥认证
3 set host [lindex $argv 0]
4 set file [lindex $argv 1]
5 spawn rsync -avR --files-from=$file / root@$host:/ #加R参数,此时若目标机器不存在同步的目录时会自动创建级联目录
6 expect {
7 "yes/no" { send "yes\r"}
8 "password:" { send "$passwd\r" }
9 }
10 expect eof
#创建文件路径的列表文件
[root@minglinux-01 /usr/local/sbin] vim file.list
1 /root/root.txt
2 /tmp/2018.txt
#创建相关文件
[root@minglinux-01 /usr/local/sbin] touch /root.txt
[root@minglinux-01 /usr/local/sbin] touch /tmp/2018.txt
#创建主机IP列表文件
[root@minglinux-01 /usr/local/sbin] vim ip.list
1 192.168.162.132
#创建用于遍历ip列表的脚本rsync.sh
[root@minglinux-01 /usr/local/sbin] vim rsync.sh
1 #!/bin/bash
1 #!/bin/bash
2 for ip in `cat ip.list`
3 do
4 echo $ip
5 ./rsync.expect $ip file.list
6 done
#执行脚本
[root@minglinux-01 /usr/local/sbin] chmod a+x rsync.expect
[root@minglinux-01 /usr/local/sbin] chmod a+x rsync.sh
[root@minglinux-01 /usr/local/sbin] sh rsync.sh
192.168.162.132
spawn rsync -avR --files-from=file.list / root@192.168.162.132:/
root@192.168.162.132's password:
building file list ... done
root/
root/root.txt
tmp/
tmp/2018.txt
sent 200 bytes received 60 bytes 173.33 bytes/sec
total size is 0 speedup is 0.00
#查看目标主机
[root@minglinux-02 ~] ls /root/root.txt
/root/root.txt
[root@minglinux-02 ~] ls /tmp/2018.txt
/tmp/2018.txt
八、批量远程执行命令
-
思路:创建一个执行指定命令的expect脚本, 然后使用一个shell脚本来循环执行这个expect脚本
-
创建exe.expect内容如下
[root@minglinux-01 /usr/local/sbin] vim exe.expect
1 #!/usr/bin/expect
2 set host [lindex $argv 0]
3 set passwd "123456"
4 set cm [lindex $argv 1]
5 spawn ssh root@$host
6 expect {
7 "yes/no" { send "yes\r"}
8 "password:" { send "$passwd\r" }
9 }
10 expect "]*"
11 send "$cm\r"
12 expect "]*"
13 send "exit\r"
- 创建 exe.sh内容如下
[root@minglinux-01 /usr/local/sbin] vim exe.sh
1 #!/bin/bash
2 for ip in `cat ip.list`
3 do
4 echo $ip
5 ./exe.expect $ip "w;free -m;ls /tmp"
6 done
- 执行脚本
[root@minglinux-01 /usr/local/sbin] chmod a+x exe.expect
[root@minglinux-01 /usr/local/sbin] sh exe.sh
192.168.162.132
spawn ssh root@192.168.162.132
root@192.168.162.132's password:
Last login: Wed Jan 16 22:27:12 2019 from 192.168.162.130
[root@minglinux-02 ~] w;free -m;ls /tmp
22:27:32 up 1 day, 22:48, 3 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.162.1 22:15 11:57 0.01s 0.01s -bash
root pts/1 192.168.162.130 22:27 0.00s 0.00s 0.00s w
root pts/3 192.168.162.1 二16 28:31m 0.05s 0.05s -bash
total used free shared buff/cache available
Mem: 1821 589 580 9 652 1047
Swap: 2047 0 2047
2018.txt
331601950@qq.com
expect.txt
mysql.sock
systemd-private-6e247fb2b41e4891b7f0ef4e53aae16d-nginx.service-CC0cwz
vmware-root
yum_save_tx.2018-12-21.16-22.lJigJq.yumtx
网友评论