一个Linux的tomcat自动部署shell脚本拆解

一个Linux的tomcat自动部署shell脚本拆解

由于服务器上安装Jenkins实现自动化部署未果,遂找寻替代方法,在网上抄了一份自动部署的脚本。这个脚本是使用shell语言进行编写,而自己此前从未接触过shell编程,于是尝试对此脚本进行逐句拆解,管中窥豹。

#! /bin/sh
echo '####################开始自动部署####################'
path=$(pwd) #当前路径
backupTime=$(date +'%Y%m%d_%H_%M_%S')
tomcatPath=/home/dev/apache-tomcat-8.5.42/ #指定tomcat文件目录名称
cd $tomcatPath/bin || exit #进入tomcat的bin目录
PID=$(ps -fu root|grep tomcat|grep -v grep|awk '{print $2}') # 现场
if [ -z "$PID" ];then
 echo "no tomcat process"
else
 echo "开始安全结束进程"
 kill -15 "$PID"
# ./shutdown.sh #停止tomcat服务
sleep 5
  if [ -z "$PID" ];then
    echo '进程'"$PID"'已安全结束'
  else
    echo '进程未安全结束,开始强制结束'
    kill -9 "$PID"
    echo '进程'"$PID"'已结束'
  fi
fi
sleep 1 #休眠1s
cd ../webapps || exit #进入tomcat的webapps目录
rm -fr helloWorld #删除helloWorld文件目录
echo '文件目录删除完成'
mv helloWorld.war ./backup/helloWorld.war."$backupTime" #备份至backup
echo '备份完成'
sleep 1 #休眠1s
cp "$path"/helloWorld.war ./ #复制war到webapps路径下
sleep 1 #休眠1s
cd ../bin || exit
./startup.sh #启动tomcat服务
echo '####################部署结束####################'

​ 脚本很简单,总共才30行。运行时首先要将文件的权限修改为可执行:chmod +x comdfile,并将文件格式设置为Unix。

  1.    #! /bin/sh
    

    shell编程是以#为注释,但对#! /bin/sh却不是。"#! /bin/sh"是对shell的声明,说明所用的是哪种类型的shell及其路径所在。(#! /bin/sh 是指此脚本使用/bin/sh来解释执行,#! 是特殊的表示符,其后面跟的是解释此脚本的shell的路径,当然路径不只此一种。)

  2. echo '####################开始自动部署####################'
    

    echo 命令用于向窗口输出文本,等价于Java里的System.out.println(),没什么好说的。

  3.    path=$(pwd) #当前路径
    

    pwd是Linux中的一个命令,可以用来查看当前工作目录的完整路径。 简单来说,在终端进行操作时,都会有一个当前工作目录。 在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置。将pwd指代的路径赋值给path变量,在后面切换目录后,path的值仍然不会改变。

  4.    backupTime=$(date +%Y%m%d_%H_%M_%S)
    

    shell中格式化日期的方法

    一)显示系统时间

    1. date CST中央标准时间——Mon Aug 23 10:52:19 CST 2021
    2. date -R 带时区的时间——Mon, 23 Aug 2021 10:52:37 +0800

    二)格式化日期

    $(date +'%Y-%m-%d %H:%M')——2021-08-21 10:51

    回到2天前:
    $(date -d '2 day ago' '+%Y/%m/%d %H:%M:%S')——2021/08/21 10:51:01

    详见Linux date命令的用法(转) - asxe - 博客园 (cnblogs.com)

  5.   tomcatPath=/home/dev/apache-tomcat-8.5.42 #指定tomcat文件目录名称
    

    类似于String a = "Hell World";没什么好说的。

  6.    cd $tomcatPath/bin || exit #进入tomcat的bin目录
    

    cd 是一个Linux的基础命令,用来切换目录,未成功则退出脚本。没什么好说的。

    $表示后面是变量。两者组合就是进入了/home/dev/apache-tomcat-8.5.42/bin这个目录。

  7.   PID=$(ps -fu root|grep tomcat|grep -v grep|awk '{print $2}')
    

    逐层拆解,整体的意思为给PID这个变量赋值,$(...)是吧括号其中的整体作为一个变量看待。

    然后是括号内的ps -fu root|grep tomcat|grep -v grep|awk '{print $2}'

    首先,|是管道符,作用就如其名,将管道左边命令的结果作为右边命令的基础。

    ps是Linux命令,作用是将某个进程显示出来。常用的是ps -efps -fu

    ps -ef

    -A  显示所有程序。
    -e  列出程序时,显示每个程序所使用的环境变量,效果与-A相同
    -f  显示UID,PPIP,C与STIME栏位,用ASCII字符显示树状结构,表达程序间的相互关系。
    -u	 以用户为主的格式来显示程序状况。
    

    202108171007165.png

    shell命令中,grep命令,是对文本行的搜索命令。

    上图中ps -ef|grep helloWorld是明显不存在这样的程序的。但是由于这条命令本身也属于一条进程,所以会将自己查出来。

    管道符连接中有一段是|grep -v grep|-v 可以过滤掉包含grep的进程行,只留下目标内容。

    ps -fu root

    由于此条命令中包含-u,所以可以携带需要查找的用户id。

    image-20210817101419264
    awk '{print $2}'是管道连接的最后一段,其中awk是Linux的文本分析语言。这段命令简单来说就是一行一行的读取管道处理结果, 以空格作为分隔符,打印第二个字段。而刚才查出来的第二个字段就是这条进程的PID。

  8. if [ -z "$PID" ];then
     echo "no tomcat process"
    else
     kill -15 "$PID"
    # ./shutdown.sh #停止tomcat服务
    sleep 2
      if [ -z "$PID" ];then
        echo '进程'"$PID"'已安全结束'
      else
        echo '进程未安全结束,开始强制结束'
        kill -9 "$PID"
        echo '进程'"$PID"'已结束'
      fi
    fi
    

    这一块放在一起看,if ... then ... fi是shell脚本的结构化命令。语法格式分为

    • if command;then command;fi (如果if满足条件然后执行then后面的command)

    • if command ... then ...else...fi (如果if满足条件然后执行then后面的command,否则则执行else后面的command)

    • if command ...then ...elif...then...多层elif...fi (如果满足if判断条件则执行then后的command动作,如果if分别满足elif判断条件则执行elif的判断条件)

    需要注意的是,if的判断条件中,使用双括号来进行来进行数值的运算,使用双方括号来进行字符串的比较。

    #!/bin/bash
    # 双括号进行数值运算
    num1=10
    if (( $num1 + 10 > 20 ))
    then
        echo "1"
    else
        echo "2"
    fi
    
    # 使用双方括号来进行字符串的比较
    if [[ `ymx` != "root" ]]
    then
            echo "ymx"
    fi
    

    比较字符写法:

    # 比较字符写法:
    -eq # 等于
    -ne # 不等于
    -gt # 大于
    -lt # 小于
    -le # 小于等于
    -ge # 大于等于
    -z  # 空串
     =  # 两个字符相等
    !=  # 两个字符不等
    -n  # 非空串
    # 举例:
    if [ $# -ge 2 ];then
    echo "你提供的参数过多!"
    exit 1
    else
     if [ $# -ne 0 ];then
      if [ $1 = s ];then
      echo "on e"
      else
      echo "two"
      fi
     else
     echo "3"
     fi
    fi
    

    上面的例子中,又出现了一个$#,而这个属于是shell中的特殊变量。

    特殊变量$0 $1 $2 $? $# $@ $*,这些变量在脚本中可以作为全局变量来使用。

    名称说明
    $0脚本名称
    $1-9脚本执行时的参数1到参数9
    $?脚本的返回值
    $#脚本执行时,输入的参数的个数
    $@输入的参数的具体内容(将输入的参数作为一个多个对象,即是所有参数的一个列表
    $*输入的参数的具体内容(将输入的参数作为一个单词)

    另外要注意的是单引号、双引号以及没有引号的区别。

    • 单引号

      可以说是所见即所得:即将单引号内的内容原样输出,或者描述为单引号里面看见的是什么就会输出什么。

    • 双引号

      把双引号内的内容输出;

      如果内容中有命令、变量等,会先把变量、命令解析出结果,然后再输出最终内容。双引号内命令或变量的写法为`命令或变量`$(命令或变量)

    • 无引号

      把内容输出,可能不会将含有空格的字符串视为一个整体输出;

      如果内容中有命令、变量等,会先把变量、命令解析结果,然后再输出最终内容;

      如果字符串中带有空格等特殊字符,则不能完整地输出,需要改加双引号。一般连续的字符串,数字,路径等可以用,不过最好全部用双引号替代之。

    最后再回过头看这一句,就很清晰了:如果"变量PID"是空为真,则输出“no tomcat process”的语句;否则执行当前目录下的shutdown.sh,即tomcat的结束命令。

  9.     kill -9 $PID
    

    kill命令是linux的杀掉进程命令。

    用法:kill [-s 信号声明|-n信号编号| -信号声明]进程号|任务声明...或kill -l [信号声明]

    这里的-9就是-n 信号编号。 当不传-*时,默认为-15。

在这里插入图片描述

举个不恰当的比喻,-15就好比皇帝给臣子赐死,臣子还可以写一下遗书,料理后事;
-9就好似当庭格杀,不给任何反应机会。

详见:Linux kill、kill-15、kill-9区别

  1. sleep 5 #休眠5s
    

    休眠命令,可以关注的一点是它不标记单位时是默认秒为单位,也可以标记单位 s、m、h;其他的没什么好说的。

  2.    rm -fr helloWorld #删除helloWorld文件目录
    

    rm命令是一个删除命令,

    参数-r可以删除目录下的所有文件及目录;

    -f可以无需逐一确认命令,并可删除唯读文件。

  3.  mv helloWorld.war ./backup/helloWorld.war."$backupTime" #备份至backup
    
     cp "$path"/helloWorld.war ./ #复制war到webapps路径下
    

    mv命令将旧的war包移动到同级目录下的backup目录,并在文件名后面加上时间变量,用作备份。

    cp命令将最开始的脚本运行目录下的新war包复制到 当前目录下。

  4. cd ../bin || exit
    ./startup.sh #启动tomcat服务
    

    切换到bin目录下,执行tomcat的启动脚本。

至此脚本执行结束。


更新

#! /bin/sh
echo '####################开始自动部署####################'
path=$(pwd) #当前路径
warName=$(ls -- *helloWorld*.war) # 打包换成了自带时间戳的格式,所以增加了获取新包的代码
tomcatPath=/home/dev/apache-tomcat-8.5.42/ #指定tomcat文件目录名称
cd "$tomcatPath"/bin || exit #进入tomcat的bin目录
PID=$(ps -fu root|grep tomcat|grep -v grep|awk '{print $2}') # 现场
if [ -z "$PID" ];then
 echo "没有正在运行的服务,开始进行下一步"
else
 echo "开始结束进程"
 kill -9 "$PID"
 echo '进程'"$PID"'已结束'
fi
sleep 1 #休眠1s
cd ../webapps || exit #进入tomcat的webapps目录
rm -fr "$(find ./ -name "*helloWorld*" -type d)" #删除解压过的文件目录
echo '文件目录删除完成'
sleep 1 #休眠1s
cp "$path"/helloWorld.war ./ #复制war到webapps路径下
sleep 1 #休眠1s
cd ../bin || exit
./startup.sh #启动tomcat服务
echo '####################部署结束####################'
  • 由于后面换成了maven打包时,自动打包成带时间戳的格式,类似于helloWorld-20211111.war这样,所以里面的war包名就不能写死了。使用了warName=$(ls -- *helloWorld*.war),动态获取war包名。
  • 由于kill -15过于不可靠(太慢了),最终还是换回了 kill -9 "$PID"
  • rm -fr "$(find ./ -name "*helloWorld*" -type d)" 删除目录也换成了动态的,使用了find指令获取当前目录下,名字为*helloWorld*规则,type(类型)为d(文件夹dir)的目录名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值