1 說明
這個shell腳本是是我編寫的第一代版本的增量代碼上線腳本,如今代碼上線腳本已更新了幾個版本,關注的技術重點是可視化對代碼版本任意回滾的上線系統(python語言編寫),後期將逐步分享這些腳本^_^ 。雖然如今看來,這個腳本寫的慘不忍睹,可是在當時卻改變了公司的上線方式,從交接工做時的手動上線,改變爲腳本自動化上線,也算是一個起點和轉折點。python
2 模塊分析這個上線腳本功能比較簡單,先請看上線整體流程:web
如下是詳細的上線流程圖:shell
3 代碼部分
請使用"notepad++"或其它編輯器打開此文檔, "alt+0"將函數摺疊後方便查閱tomcat
#!/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" resin@$REMOTE_IP:$2 $3 | tee -a $LOG_PATH sleep 2 echo "第二次進行判斷" rsync -vzrtopg --delete --progress "-e ssh -p $PARTS" resin@$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 resin@$REMOTE_IP:$3 | tee -a $LOG_PATH sleep 2 echo "第二次" rsync -vzrtopg --progress "-e ssh -p $PARTS" $1 resin@$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" resin@$REMOTE_IP:$2 $3 | tee -a $LOG_PATH sleep 2 echo "第二次" rsync -vzrtopg --delete --progress "-e ssh -p $PARTS" resin@$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腳本,算是初期練手之做,很難一下看明白是確定的,總體寫的很爛,可是在小地方的一些小技巧,確實可讓各位小夥伴們借鑑一下。bash
但願經過這系列的文章記錄本身成長的腳步,沒有誰能一會兒就變成大牛,通過時間的打磨,讓咱們一步一步的脫變吧!!!服務器
腳本不足之處:app
1. 代碼可讀性太差ssh
2. rsync執行是否完成正確性沒有檢查webapp
3. rsync沒有進行超時處理編輯器