第十九章 Shell编程(三)

一、 分发系统介绍
二、 expect脚本远程登录
三、 expect脚本远程执行命令
四、 expect脚本传递参数
五、 expect脚本同步文件
六、 expect脚本指定host和要同步的文件
七、 构建文件分发系统
八、 批量远程执行命令
九、 扩展

一、 分发系统介绍

由于业务迭代更新,经常需要更改代码,如果机器很多,此时为了快速更新代码就可以使用分发系统,把更新的代码分别发布到机器上去。其中开源的上线代码的软件有很多,如git等等。这里我们使用shell来编写一个分发系统来上线代码。核心使用expect脚本语言,它可以实现远程执行命令,远程传输数据等操作。

准备工作

1.准备1台模版机器,里面是包含有最新的代码

2.每台分发机器的IP地址和密码

3.分发系统脚本

由于分发系统的核心是使用expect,因此先实践几个例子来熟悉expect的语法命令。

安装expect:

yum install -y expect   # 可以使用yun安装expect软件

实验环境:

扫描二维码关注公众号,回复: 4963800 查看本文章

# 实验需要两台主机

分发主机1:192.168.1.128

远程主机2:192.168.1.138

二、 expect脚本远程登录

1. 在expect分发主机上安装expect

[root@Linux01 ~]# yum install -y expect
2. 编辑脚本

[root@Linux01 ~]# cd /usr/local/sbin/

[root@Linux01 sbin]# vim 1.expect

#!/usr/bin/expect
set host "192.168.1.138"                             # 设置变量,目标主机的ip
set passwd "931223"                                  # 设置变量,目标主机的用户密码
spawn ssh root@$host  # 自动交互开始,在Expect自动交互程序执行的过程中,spawn命令是一开始就需要使用的命令
expect {
"yes/no" { send "yes\r";exp_continue }
"assword:" { send "$passwd\r" }                #输入密码 $passwd\r 。匹配的字符串不加p是因为不清楚是大写还是小写
}
interact
注:大括号的两边都需要有空格

// set 定义变量

// spawn 执行命令

// expect 使用expect语句进行交互

// \r表示回车

// exp_continue表示继续 expect语句

// interact表示expect脚本结束了,但还在继续交互(即停留在远程登录的主机上);也可以写成expect eof,表示停留远程机器上一会儿再退出;如果两个都不加,在登录远程主机时,直接退出

//为了让远程登录时候出现提示,可以清空/root/.ssh/known_hosts目录

3. 测试脚本

①添加执行权限

[root@Linux01 sbin]# chmod +x ./1.expect
②执行脚本

[root@Linux01 sbin]# ./1.expect

[root@zabbix-agent ~]#                                     #进入远程主机
 

三、 expect脚本远程执行命令

自动远程登录,并执行命令并退出

1. 编辑脚本2.expect

[root@Linux01 sbin]# vim 2.expect

#!/usr/bin/expect
set host "192.168.1.138"
set passwd "931223"
spawn ssh root@$host
expect {
"yes/no" { send "yes\r"; exp_continue}
"assword:" { send "$passwd\r"}
}
expect "]*"                     # 匹配字符串 ]*   *号代表通配任意字符
send "touch /tmp/exp.txt\r"  # 输入命令 touch /tmp/exp.txt 
expect "]*"
send "echo "expect test"  > /tmp/exp.txt\r" # 输入命令 echo "expect test" >/tmp/exp.txt
expect "]*"
send "exit\r"                    # 输入命令 exit   退出目标主机
2. 验证

[root@Linux01 sbin]# chmod +x 2.expect     #添加可执行权限

[root@Linux01 sbin]# ./2.expect
.......

再登录192.168.1.138查看文件是否创建

[root@zabbix-server ~]# cat /tmp/exp.txt

expect test

四、 expect脚本传递参数

1. 编辑脚本3.expect

[root@Linux01 sbin]# vim 3.expect

#!/usr/bin/expect
set user [lindex $argv 0]  #  调用第一个参数  给变量user   用户名
set host [lindex $argv 1]  # 调用第二个参数 给变量host     ip
set passwd "931223"
set cm [lindex $argv 2]    #调用第三个参数 给变量cm       需要执行的命令,有多个命令时需要用""双引号括起来并使用;分号分开
spawn ssh $user@$host

expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect "]*"
send "$cm\r"
expect "]*"
send "exit\r"

2. 测试

[root@Linux01 sbin]# chmod +x 3.expect

# 执行脚本,带上参数,第一个参数是登录目标主机的用户, 第二个参数是目标主机的ip 第三个参数是需要执行的命令

[root@Linux01 sbin]# ./3.expect root 192.168.1.138 "echo 'parameter test' >> /tmp/exp.txt"

执行完命令后,自动退出远程主机,再次登录远程主机查看文件内容是否添加

[root@Linux01 sbin]#cat /tmp/exp.txt

expect test

parameter test

五、 expect脚本同步文件

1. 编辑脚本4.expect

[root@Linux01 sbin]# vim 4.expect

#!/usr/bin/expect
set passwd "931223"
spawn rsync -av [email protected]:/tmp/exp.txt /tmp/  #核心命令,把远程主机文件同步到分发主机
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof    
# 当一个命令需要一定时间才能执行完的情况下,脚本最后需要加expect eof命令, 可以等待命令执行完毕才会结束脚本
# 还有在send执行的shell命令的下一行添加一个超时时间  timeout , 
# 例如: timeout 5 为5秒超时。 -1为永不超时

2. 测试

[root@Linux01 sbin]# chmod +x 4.expect

[root@Linux01 sbin]# ./4.expect

.....

[root@Linux01 sbin]#cat /tmp/exp.txt

expect test

parameter test

六、 expect脚本指定host和要同步的文件

指定目标主机和需要同步的文件, 将文件同步到目标主机上,此方式只能同步一个文件或者目录

1. 编辑脚本5.expect

[root@Linux01 sbin]# vim 5.expect

#!/usr/bin/expect
set passwd "931223"
set host [lindex $argv 0]   #第一个参数指定目标主机的ip
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. 测试

[root@Linux01 sbin]# touch 110.txt     #创建一个文件

[root@Linux01 sbin]# chmod +x 5.expect

[root@Linux01 sbin]#./5.expect 192.168.1.138 /root/110.txt            # 参数使用刚才创建文件的绝对路径

....

再检查远程主机192.168.1.138的/root 目录下是否有同步过去的文件

七、 构建文件分发系统

需求背景:

对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。

实现思路首先要有一台模板机器,把要分发的文件准备好,

然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可。

核心命令: rsync -av --files-from=list.txt / root@host:/
1.编辑rsync.expect脚本

[root@Linux01 sbin]# vim rsync.expect

#!/usr/bin/expect
set passwd "931223"
set host [lindex $argv 0]
set file [lindex $argv 1]
spawn rsync -avR --files-from=$file / root@$host:/    # R选项可以在目标主机中不存在同步的目录时自动创建相关目录 
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}
expect eof

[root@Linux01 sbin]#chmod +x rsync.expect
2. 创建ip.list 同步机器的IP列表

[root@Linux01 sbin]#vim /tmp/ip.list

//内容如下

192.168.1.138

192.168.1.135

...

3. 创建file.list 需要同步文件的列表

[root@Linux01 sbin]#vim /tmp/file.list

//添加如下内容

/tmp/exp.txt

/tmp/test.txt

...

4. 创建 rsync.sh 脚本

[root@Linux01 sbin]#vim rsync.sh

#!/bin/bash

for ip in `cat ip.list`

  do

    echo $ip .

    ./rsync.expect $ip /tmp/file.list

done

[root@Linux01 sbin]#chmod +x ./rsync.sh

5. 测试

[root@Linux01 sbin]#./rsync.sh

...

登录ip在ip.list里的远程主机,查看文件是否同步。

注:这个文件分发系统有一个弊端,所有同步的主机都需要使用相同的密码, 而且有泄露密码的风险。

但是也可以使用密钥认证登录的方式来解决这个问题。

八、 批量远程执行命令

当同步完代码后有可能需要批量地重启服务,因此还需要批量远程执行命令,类似于自动化。

思路:创建一个执行指定命令的expect脚本, 然后使用一个shell脚本来循环执行这个expect脚本

1. 编辑exe.expect脚本

[root@Linux01 sbin]#vim exe.expect

#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "931223"
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"

[root@Linux01 sbin]#chmod +x exe.expect
2. 创建 exe.sh 脚本文件,内容如下, 这里又用到了之前的 ip.list 主机列表文件

[root@Linux01 sbin]#vim exe.sh

#!/bin/bash
for ip in `cat ip.list`               # 遍历主机IP列表
do
    echo $ip
    ./exe.expect $ip "w;free -m;df -h"  执行exe.expect脚本, 指定主机ip 和需要执行的命令 
done

[root@Linux01 sbin]#chmod +x  exe.sh
3. 测试

[root@Linux01 sbin]#./exe.sh

九、 扩展

shell多线程 http://blog.lishiming.net/?p=448

(shell电子书)
shell习题做一下 http://www.apelearn.com/study_v2/chapter15.html#shll

猜你喜欢

转载自blog.csdn.net/dwy2018/article/details/86517354