粗浅的增量代码上线shell脚本--菜鸟版

1      说明

这个shell脚本是是我编写的第一代版本的增量代码上线脚本,现在代码上线脚本已更新了几个版本,关注的技术重点是可视化对代码版本任意回滚的上线系统(python语言编写),后期将逐步分享这些脚本^_^ 。虽然现在看来,这个脚本写的惨不忍睹,但是在当时却改变了公司的上线方式,从交接工作时的手动上线,改变为脚本自动化上线,也算是一个起点和转折点。

2      模块分析

这个上线脚本功能比较简单,先请看上线总体流程:

以下是详细的上线流程图:

3      代码部分

请使用"notepad++"或其它编辑器打开此文档, "alt+0"将函数折叠后方便查阅

#!/bin/sh
#set -x
#auther: gushao
#time: 2014-5-30

#设置初始变量
#$1 参数说明 1  前台   2  后台   3  app

#用于区分测试环境上线和生产环境上线
env_test=1
case $env_test in
1)
REMOTE_IP=192.168.1.110
PARTS=22
#用于服务器重启时用
REMOTE_IP10=192.168.1.110
REMOTE_IP11=192.168.1.111
REMOTE_IP12=192.168.1.112
PARTS_RESIN10=22
PARTS_RESIN11=22
PARTS_RESIN12=22
;;
2)
REMOTE_IP=211.162.125.207
PARTS=1573
#用于服务器重启时用
REMOTE_IP10=211.***.125.2**
REMOTE_IP11=211.***.125.***
REMOTE_IP12=211.**.125.***
PARTS_RESIN10=1573
PARTS_RESIN11=10011
PARTS_RESIN12=10012
;;
*)
echo "输入参数有无,选择测试或正式环境"
exit 1
;;
esac

#中间路径变量
edir=`date +%Y-%m-%d`/`date +%H%M%S`
rdate=`date +%Y-%m-%d_%H%M%S`
NDATE=`date +%Y-%m-%d\ %H:%M:%S`
DET_RYD=/home/resin/project_name #本地同步代码
DET_TOMCAT=/home/resin/tomcat/webapps
DET_APP=/opt/tomcat_app/webapps
#用于ssh同步时,需要同步到的目录
DET_RYD_HOME=/home/resin/
DET_TOMCAT_HOME=/home/resin/tomcat
DET_APP_HOME=/opt/tomcat_app
SOURCE_RYD="/home/demo/demo_ryd/project_name"   #存放需要升级的代码路径
SOURCE_TOMCAT="/home/demo/demo_tomcat/webapps"
SOURCE_APP="/home/demo/demo_app/webapps"
#日志保存位置
LOG_RYD_BACK=/home/resin/log_back/project_name
LOG_TOMCAT_BACK=/home/resin/log_back/tomcat
LOG_APP_BACK=/home/resin/log_back/APP
LOG_PATH=/home/resin/codeupdate.log                          #日志文件位置
#将改变的代码,从服务器上保存到制定的路径
REVAL_RYD=/home/resin/reval_back/ryd/ryd
REVAL_TOMCAT=/home/resin/reval_back/tomcat/tomcat
REVAL_APP=/home/resin/reval_back/app/app
#保存这次上传的代码
CODE_RYD_BACK=/home/resin/code_bak/ryd/ryd
CODE_TOMCAT_BACK=/home/resin/code_bak/tomcat/tomcat
CODE_APP_BACK=/hom/resin/code_bak/app/app
DEBUG=1
#调试模块,判断代码执行结果,指令执行出错后输出出错信息
function altert() {
#usage:alert <$?> <object>
if [ "$1" -ne 0 ]
then 
  echo "[warn]:$2 指令执行错误" >&2
  echo "指令执行错误,请检查错误原因,继续请回车"
  read x
fi
} 
#此函数的做用是遍历$1的目录source,寻找$2目录中是否有一致的文件det,并输出不同的信息
#本脚本中此函数的变量$1为需要上传的文件,$2是服务器同步到本地的文件
function ergodic(){
#echo "$4"
INIT_PATH=$3
#usage: ergodic $1  $2 $3=$1
 for file in ` ls $1`
 do
   
   #此段代码的目的,是通过文本的方式完整文件或目录路径
   echo ${1}/${file}  > /tmp/tmp_wenijian.txt
   #然后将路径替换$1删除,替换为${DET}的路径
   eval sed -i "s#${INIT_PATH}##"  /tmp/tmp_wenijian.txt
   UNX=`cat /tmp/tmp_wenijian.txt | head -n 1`
   DET1=${2}$UNX
   path_a=${file}
   if [ -d ${1}/${file} ];then
        ergodic ${1}/${file} ${2} $3 $4 
   else
        #此代码段目的,用于无论循环到哪层目录,通过完成路径截取
        echo ${1}/${file}  > /tmp/tmp_wenijian.txt
        eval sed -i "s#${INIT_PATH}##"  /tmp/tmp_wenijian.txt
                #unx是去除文件投的相对路径
        UNX=`cat /tmp/tmp_wenijian.txt | head -n 1`
        DET1=${2}$UNX
                   if [ -e ${DET1} ];then
              echo "[info][$NDATE]检测到改变文件:$UNX"   | tee -a  $LOG_PATH
              #此代码的目的是复制的时候讲文件的路径一起
                          cp  --parent ${2}$UNX  $4_${rdate}
          else
              echo "[warn][$NDATE]检测到新文件:$UNX"   | tee -a  $LOG_PATH
            fi
    fi
 done
}
#此函数的做用是遍历$1的目录,并对比$2中的文件,是否一致,输出不同的信息
function DIFF_RYD(){
INIT_PATH=$3
  for file in ` ls $1`
  do
     echo ${1}/${file}  > /tmp/tmp_wenijian.txt
     eval sed -i "s#${INIT_PATH}##"  /tmp/tmp_wenijian.txt
     UNX=`cat /tmp/tmp_wenijian.txt | head -n 1`
     DET1=${2}$UNX
     path_a=${file}
        if [ -d ${1}/${file} ];then
                   DIFF_RYD ${1}/${file} ${2} $3
        else
           echo ${1}/${file}  > /tmp/tmp_wenijian.txt
           eval sed -i "s#${INIT_PATH}##"  /tmp/tmp_wenijian.txt
           UNX=`cat /tmp/tmp_wenijian.txt | head -n 1`
           DET1=${2}$UNX
                         if [ -e ${DET1} ];then
                    #比较上传到生产的文件和上传文件的差异
                    diff -q  ${DET1}  ${1}/${file}   | tee -a  $LOG_PATH
                  else
                     echo  "[error][$NDATE]上传文件与本地文件不同步,请检测"   | tee -a  $LOG_PATH
                     echo "[warn][$NDATE]检测到新文件:${1}/${file}"   | tee -a  $LOG_PATH
                  fi
        fi
  done
}
#project_name上传代码,$1是需要上传的代码SOURCE,$2是本地的同步目录DET,$3是同步代码的上一级目录DET_HOME
#$4是${CODE_BACK},$5是${LOG_BACK},$6是${REVAL},$7 remote_ip ,$8 port
#$INIT_PATH是需要上传的代码,$DET是本地同步的代码,$DET_HOME是同步代码的上一级目录
function MODEL_UPLOAD() {

#同步上产脚本主体函数

#预先创建各类自定义目录
test -e $2     || mkdir -p  $2
test -e $4_${rdate}     || mkdir -p  $4_${rdate}
test -e $5     || mkdir -p  $5
test -e $6_${rdate}     || mkdir -p  $6_${rdate}
test -e $1 || echo "[error][$NDATE]没有找到${2}部署文件"  | tee -a  $LOG_PATH
test -e $1 || exit
echo ‘%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%‘ >  $LOG_PATH
echo "[info][$NDATE]开始自动部署${2}版本上传"  | tee -a  $LOG_PATH
chown -R resin:resin  $1
#这个我定义的函数
ergodic $1 $2 $1 $6
chown -R resin:resin  $2
echo "--------------------------------"   | tee -a  $LOG_PATH
echo "判断两次同步期间${2}服务器是否有改动"   | tee -a  $LOG_PATH
rsync -vzrtopg  --delete --progress "-e ssh -p $PARTS"  [email protected]$REMOTE_IP:$2   $3  | tee -a  $LOG_PATH
sleep 2
echo "第二次进行判断"
rsync -vzrtopg  --delete --progress "-e ssh -p $PARTS"  [email protected]$REMOTE_IP:$2   $3  | tee -a  $LOG_PATH
echo "判断结束"  | tee -a  $LOG_PATH
echo "-------------------"   | tee -a  $LOG_PATH
echo "-----------------------------------------"
echo "将本地文件同步到远程服务器"  | tee -a  $LOG_PATH
rsync -vzrtopg   --progress "-e ssh -p $PARTS" $1  [email protected]$REMOTE_IP:$3   | tee -a  $LOG_PATH
sleep 2
echo "第二次"
rsync -vzrtopg   --progress "-e ssh -p $PARTS" $1  [email protected]$REMOTE_IP:$3   | tee -a  $LOG_PATH
echo "------------------------------------------"  | tee -a  $LOG_PATH
echo "将改变文件同步到本地服务器"  | tee -a  $LOG_PATH
rsync -vzrtopg   --progress "-e ssh -p $PARTS" $1  $3   | tee -a  $LOG_PATH
echo "--------------------------------------------------"
#此操作用于对比上传的文件和服务器同步到本地文件是否一致
echo "将运程服务器与本地服务器同步"  | tee -a  $LOG_PATH
rsync -vzrtopg  --delete --progress "-e ssh -p $PARTS"  [email protected]$REMOTE_IP:$2   $3  | tee -a  $LOG_PATH
sleep 2
echo "第二次"
rsync -vzrtopg  --delete --progress "-e ssh -p $PARTS"  [email protected]$REMOTE_IP:$2   $3  | tee -a  $LOG_PATH
echo "------------------------------"   | tee -a  $LOG_PATH
echo "文件检测开始:"    | tee -a  $LOG_PATH
DIFF_RYD $1 $2 $1 
echo "文件检测结束"    | tee -a  $LOG_PATH
echo "-------------------------------------------------------------------------------------"    | tee -a  $LOG_PATH
#将此次需要长传的文件打包保存
mv  $1  $4_${rdate}
echo "文件上传结束"
#cat $LOG_PATH
cat $LOG_PATH > $5/${rdate}.log
}

case $1 in
1)
MODEL_UPLOAD $SOURCE_RYD $DET_RYD $DET_RYD_HOME $CODE_RYD_BACK $LOG_RYD_BACK $REVAL_RYD
;;
2)
MODEL_UPLOAD $SOURCE_TOMCAT $DET_TOMCAT  $DET_TOMCAT_HOME $CODE_TOMCAT_BACK  $LOG_TOMCAT_BACK $REVAL_TOMCAT 
;;
3)
MODEL_UPLOAD $SOURCE_APP $DET_APP  $DET_APP_HOME $CODE_APP_BACK  $LOG_APP_BACK $REVAL_APP
;;
*)
echo "Usage:$0 {1project_name|2tomcat|3app}" | tee -a  $LOG_PATH
exit 1
;;
esac
exit 0

这个shell脚本,算是初期练手之作,很难一下看明白是肯定的,整体写的很烂,但是在小地方的一些小技巧,确实可以让各位小伙伴们借鉴一下。

希望通过这系列的文章记录自己成长的脚步,没有谁能一下子就变成大牛,经过时间的打磨,让我们一步一步的脱变吧!!!

脚本不足之处:

1. 代码可读性太差

2. rsync执行是否完成正确性没有检查

3. rsync没有进行超时处理

时间: 2024-10-13 12:12:22

粗浅的增量代码上线shell脚本--菜鸟版的相关文章

Java代码调用Shell脚本并传入参数实现DB2数据库表导出到文件

本文通过Java代码调用Shell脚本并传入参数实现DB2数据库表导出到文件,代码如下: import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.util.HashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import

使用sqoop从mysql往hive中增量导数据shell脚本

一:sqoop增量导入的两种方式 Incremental import arguments: Argument Description --check-column (col) Specifies the column to be examined when determining which rows to import. (the column should not be of type CHAR/NCHAR/VARCHAR/VARNCHAR/ LONGVARCHAR/LONGNVARCHA

通过Git WebHooks+脚本实现自动更新发布代码之Shell脚本(二)

依据前文<通过Git WebHooks+脚本实现自动更新发布代码>的解决方案编写的shell脚本,此脚本专门用于更新补丁文件,例如对项目中的文件实现增(add).删(remove).改(update),并且执行相关的命令,如清除缓存.重启服务等. 此Shell脚本目前设计成在本地执行,目前不适合分布式执行的情况.也就是说,此脚本最好与项目在同一个机器上,这个缺陷已经标注在脚本中了,参见脚本中的多个TODO. 脚本完成的工作: 检查配置文件合规性 备份与恢复 增删改文件 执行命令 失败回滚 除上

通过Git WebHooks+脚本实现自动更新发布代码之shell脚本

前文讲述了<通过Git WebHooks+脚本实现自动更新发布代码>,里面提供了一种自动更新发布代码的脚本编写思路.本文的脚本与前文中的思路不太不同.本脚本以capistrano中的一些思想和理念为依据,用简单好理解的shell脚本实现capistrano原本实现的自动化部署部分. 脚本的一些特点和功能: 解决脚本的符号链接问题,准确获取脚本工作目录(从tomcat脚本中学到): 颜色显示,不同级别的信息用不同的颜色显示(共两种方案,前一种从一位不知名的国外工程师处得到,后一种从lnmp1.2

CENTOS 7 内网网段在用IP地址检测Shell脚本优化版

脚本内容 #!/bin/bash ############################################################################# # 用途:网段IP地址检测 # 作者:Dylan # 日期:2019年10月31日 11:56 ############################################################################# #############################

Shell脚本实现DB2数据库表导出到文件

该Shell脚本用于实现将DB2数据库表导出到文件,将在另一篇博文<Java代码调用Shell脚本并传入参数实现DB2数据库表导出到文件>中通过Java代码实现调用该脚本并传入参数. 1 #!/usr/bin/env sh 2 3 DBSCHEMA=$1 4 DBUSER=$2 5 DBPASSWORD=$3 6 TABLENAME=$4 7 FILEPATH=$5 8 DELIMITER=$6 9 EXPORTLIMIT=$7 10 11 SQLERR="NO ERROR MSG&

CentOS6.7下使用非root用户(普通用户)编译安装与配置mysql数据库并使用shell脚本定时任务方式实现mysql数据库服务随机自动启动

CentOS6.7下使用非root用户(普通用户)编译安装与配置mysql数据库并使用shell脚本定时任务方式实现mysql数据库服务随机自动启动1.关于mysql?MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司.MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性.特点: Mysql是开源的,所以你不需要支付额外的费用.Mysql支持大型的数据库.可以处理拥有上千

shell 脚本实战笔记(10)--spark集群脚本片段念念碎

前言: 通过对spark集群脚本的研读, 对一些重要的shell脚本技巧, 做下笔记. *). 取当前脚本的目录 sbin=`dirname "$0"` sbin=`cd "$sbin"; pwd` 代码评注:# 以上代码为获取执行脚本所在的目录的常用技巧# sbin=$(dirname $0) 返回可能是相对路径, 比如./ # sbin=$(cd $sbin; pwd) 采用pwd, 来返回脚本所在目录的绝对路径 *). 循环遍历脚本参数 while (( &q

Shell脚本的学习(一)

Shell脚本的学习(一) 一)代码式shell脚本简介 1.下载 Xshell 5 建一个文件夹 mkdri home/data ; 1)查看一个在data里建一个1.sh 查看是否建立成功. 2)并编辑echo hello word,并保存推出 3)运行脚本时发现没有权限.添加权限.   ```绿色可执行脚本 二)shell脚本命令 1>下载EverEdit编辑器,其他编辑器也可以的 安装后     2>变量: 1.当没有那个变量是结果取值为空,取值时${name}括号可加可不加