【小项目】使用shell和expect实现简易的文件分发系统

简介:

所谓分发系统就是一个主要用来上线代码或同步文件的脚本,先来看一下需求背景:

  • 我们的一个网站在很多台服务器上跑着,假设这个网站的后端是使用PHP编写的,那么当这个后端的PHP代码需要更新或扩展的时候,要如何将这些更新、扩展的代码全部都发布到这些服务器上?

所以分发系统就是用来完成以上这个需求的,分发系统需要完成的事情就是将需要上线的代码分发到这些线上服务器中。我们现在要做的就是实现这个分发系统,实现这个系统需要用到两个主要的东西就是shell和expect,通过shell结合expect可以编写一个简单的分发系统。

<br>

构建文件分发系统


  • 需求背景:
    对于大公司而言,肯定时不时会有网站或者配置文件更新,而且使用的机器肯定也是好多台,少则几台,多则几十甚至上百台。所以,自动同步文件是至关重要的。
  • 实现思路:
    首先要有一台模板机器,把要分发的文件准备好,然后只要使用expect脚本批量把需要同步的文件分发到目标机器即可。
  • 核心命令:
    rsync -av --files-from=list.txt / root@host:/

文件分发系统的实现:
1.使用expect编写一个脚本文件rsync.expect,这个脚本是实现文件同步的脚本,内容如下:

[root@localhost ~/expectFiles]# vim rsync.expect
#!/usr/bin/expect
# 目标机器的登录密码
set passwd "123456"
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
[root@localhost ~/expectFiles]# chmod a+x rsync.expect

2.然后再编辑一个文本文件,这个文件用来放需要同步的文件列表,例如我这里随便同步几个文件:

[root@localhost ~/expectFiles]# vim /tmp/list.txt
/tmp/12.txt
/root/test.sh
/tmp/test.txt
/root/expectFiles/hostFile.expect

提示:如果你的rsync命令没有加-R选项的话,就需要确保目标机器也有这个文件列表中所定义的目录路径,不然就会报错。

3.还需要编辑一个ip.list,用于存放需要同步的目标机器的IP地址,例如我需要将文件都同步这几个IP的机器上:

[root@localhost ~/expectFiles]# vim /tmp/ip.list
192.168.77.128
192.168.77.130

需要同步的目标机器的密码最好是一致的,因为只是做实验为了简单化就不使用密钥验证了。

4.再编写一个shell脚本rsync.sh,这个脚本比较简单,只是遍历出ip.list文件内容然后交给rsync.expect脚本去执行而已,示例:

[root@localhost ~/expectFiles]# vim rsync.sh
#!/bin/bash
for ip in `cat /tmp/ip.list`
do
    echo $ip
    # 第二个参数就是需要同步的文件列表
    ./rsync.expect $ip /tmp/list.txt
done

最后我们只需要执行rsync.sh脚本即可:

[root@localhost ~/expectFiles]# sh rsync.sh 
192.168.77.128
spawn rsync -avR --files-from=/tmp/list.txt / root@192.168.77.128:/
root@192.168.77.128's password: 
building file list ... done
root/
root/test.sh
root/expectFiles/
root/expectFiles/hostFile.expect
tmp/
tmp/12.txt
tmp/test.txt

sent 666 bytes  received 97 bytes  1526.00 bytes/sec
total size is 288  speedup is 0.38
192.168.77.130
spawn rsync -avR --files-from=/tmp/list.txt / root@192.168.77.130.83:/
root@192.168.77.130's password: 
building file list ... done
root/
root/test.sh
root/expectFiles/
root/expectFiles/hostFile.expect
tmp/
tmp/12.txt
tmp/test.txt

sent 666 bytes  received 97 bytes  1526.00 bytes/sec
total size is 288  speedup is 0.38
[root@localhost ~/expectFiles]# 

运行结果如上,没有报错,文件也正常同步了,这样我们就实现了一个很简单的文件分发系统。

<br>

批量远程执行命令


以上我们已经实现了简单的文件分发系统,但是光只能同步文件还不够。因为假设这是网站的后端代码文件,同步完了之后需要重启web服务或者执行一些命令,所以还得再编写一个能够批量远程执行命令的脚本。

1.同样的先使用expect编写远程登录的脚本文件exe.expect, 内容如下:

[root@localhost ~/expectFiles]# vim exe.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "123456"
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@localhost ~/expectFiles]# chmod a+x exe.expect

2.除此之外还需要写一个shell脚本exe.sh,这个脚本和rsync.sh差不多都是遍历出ip.list文件里的ip,内容如下:

[root@localhost ~/expectFiles]# vim exe.sh
#!/bin/bash
for ip in `cat /tmp/ip.list`
do
    echo $ip
    # 第二个参数就是需要执行的命令
    ./exe.expect $ip "who;ls"
done

执行exe.sh脚本:

[root@localhost ~/expectFiles]# sh exe.sh 
192.168.77.128
spawn ssh root@192.168.77.128
root@192.168.77.128's password: 
Last login: Wed Nov 29 21:56:41 2017 from 192.168.77.130
[root@localhost ~]# who;ls
root     pts/0        2017-11-29 21:26 (192.168.77.1)
root     pts/1        2017-11-29 21:57 (192.168.77.130)
\                mysql57-community-release-el7-8.noarch.rpm  Test.java
anaconda-ks.cfg  stop.sh                                     test.sh
expectFiles      Test.class                                  zabbix-release-3.2-1.el7.noarch.rpm
[root@localhost ~]# 192.168.77.130
spawn ssh root@192.168.77.130
root@192.168.77.130's password: 
Last login: Thu Nov 30 05:49:18 2017 from 192.168.77.130
[root@localhost ~]# who;ls
root     tty1         2017-11-30 05:23
root     pts/0        2017-11-30 03:33 (192.168.77.1)
root     pts/2        2017-11-30 05:50 (192.168.77.130)
accept_local~  expectFiles  grep  logs  sed  shellFile  Test  test.sh
[root@localhost ~]# [root@localhost ~/expectFiles]# 

运行结果如上,没毛病。

done:至此简易的分发系统和批量远程执行命令的功能就完成了。




本文转自 ZeroOne01 51CTO博客,原文链接:http://blog.51cto.com/zero01/2045828,如需转载请自行联系原作者

相关文章
|
7月前
|
Shell Android开发
Android系统 adb shell push/pull 禁止特定文件
Android系统 adb shell push/pull 禁止特定文件
603 1
|
2月前
|
Shell
Shell 文件包含
10月更文挑战第5天
38 4
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
2月前
|
监控 网络协议 Shell
ip和ip网段攻击拦截系统-绿叶结界防火墙系统shell脚本
这是一个名为“小绿叶技术博客扫段攻击拦截系统”的Bash脚本,用于监控和拦截TCP攻击。通过抓取网络数据包监控可疑IP,并利用iptables和firewalld防火墙规则对这些IP进行拦截。同时,该系统能够查询数据库中的白名单,确保合法IP不受影响。此外,它还具备日志记录功能,以便于后续分析和审计。
60 6
|
1月前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
4月前
|
Shell Linux 网络安全
在Linux中,如何利用Shell把10台主机的当前时间写到一个文件里边?
在Linux中,如何利用Shell把10台主机的当前时间写到一个文件里边?
|
5月前
|
Shell 测试技术 Linux
Shell 脚本循环遍历日志文件中的值进行求和并计算平均值,最大值和最小值
Shell 脚本循环遍历日志文件中的值进行求和并计算平均值,最大值和最小值
73 3
|
4月前
|
Shell Linux 开发工具
在Linux中,如何编写shell脚本将当前目录下大于10K的文件转移到/tmp目录下?
在Linux中,如何编写shell脚本将当前目录下大于10K的文件转移到/tmp目录下?
|
4月前
|
Shell Linux Perl
在Linux中,编写一个shell脚本,用于统计指定目录下所有文件的行数。
在Linux中,编写一个shell脚本,用于统计指定目录下所有文件的行数。
|
5月前
|
Shell 应用服务中间件 Linux
shell 实现项目的启动与停止
shell 实现项目的启动与停止
28 0