shell脚本自动化执行jar包

需要用shell脚本来自动化执行jar包,以后可以用jenkins来CI/CD,记录一下对应实现。

实现需求

  1. 以命令行执行shell传入的第一个参数为jar名进行执行。
  2. 对应jar已存在执行进程,关闭对应进程后再执行。
  3. 以后台方式执行对应的jar包,输出log文件并判断是否成功执行。

测试用jar包和功能

为了保持进程执行不退出,主程序写死循环输出时间。
jar名为shellTestDemo.jar

public class MainApplication {
    public static void main(String[] args){
        while(true){
            try {
                System.out.println(new Date());
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

shell实现

名称读取并判断是否存在

#!/bin/bash

# 传参作为jar名称
application_name=${1}
application_place="/home/huiluczp/huiluczp/${application_name}"

# 判断文件名以及是否存在
if [ -z $( echo ${application_name} | grep '.*.jar$' ) ];
    then
        echo "jar名称不规范,退出"
        exit 1
    else
        echo "jar名称为${application_name}"
fi

if [ -e ${application_place} -a -f ${application_place} ]
    then
        echo "jar存在,开始build工作"
    else
        echo "jar不存在,退出"
        exit 1
fi

${1}获取第一个传入参数,利用正则进行名称格式的判断,判断式来判断对应路径下是否存在对应jar,确定存在后进行后续处理。

判断对应进程是否存在

# 先判断是否有对应的进程存在
echo "开始进程清理工作"
pid=$(ps -ef | grep "${application_name}" | grep 'java -jar' | grep -v 'grep' | awk '{print $2}')

命令首先用ps来找到所有进程信息,并使用grep匹配对应jar名称和java进程。为了防止把grep命令执行进程也算进去,使用-v参数来剔除对应进程信息。最后使用awk来获取对应的pid。

停止现有进程

包括两部分,停止现有进程和判断是否成功。

# 存在则杀死已存在进程

if [ -z ${pid} ];
    then
        echo "进程${pid}不存在"
    else
        # 可能会有多个进程,分别处理
        for p in ${pid}
        do
            echo "进程${p} killing"
            kill -15 ${p}
            sleep 1
        done
fi

考虑可能会有数个进程同时存在,循环进行kill。

# 循环判断是否成功杀死进程
final=''
while [ -z ${final} -a ![ -z ${pid} ] ];
    do  
        for p in ${pid}
        do
            result=$(ps -ef | grep -w ${p} | grep 'java')
            if [ -z ${result} ];
                then
                    echo "进程${p}已被杀死, 开始build ${application_name}"
                    final='true'
                else
                    echo "进程${p}未被杀死, 继续尝试"
                    final=''
                    kill -9 ${p}
                    sleep 1
            fi
        done
    done

while循环,final作为flag,每一次碰上未被停止的进程就将其置空,保证将所有的进程都kill之后再进行下一步。

启动jar并判断是否成功

# jar启动
echo "进程check完成, 启动${application_name}, 位置为${application_place}"
sleep 1
`nohup java -jar ${application_place} > ./log.txt 2>&1 &`

使用nohup将java程序在后台执行,将输出结果存到log.txt中,并将错误信息也写入。

# 判断启动是否成功(5次最高)
for (( i=1; i<6; i=i+1))
    do
        pid=$(ps -ef | grep ${application_name} | grep 'java -jar' | grep -v 'grep' | awk '{printf $2}')
        if [ -z ${pid} ];
            then
                echo "进程不存在, 正在重试"
                sleep 1
            else
                echo "进程${pid}启动成功"
                exit 0
        fi
done
exit 1

循环判断进程是否成功启动,不成功就算了,成功立刻exit

效果展示

shell脚本自动化执行jar包_第1张图片
手动启动jar程序,pid17193。
shell脚本自动化执行jar包_第2张图片
执行脚本,停止现有进程,并执行新进程17225。中间有个错误提示,因为grep pid的时候拿到的是一个类似数组的东西,直接-z的时候会报错,不过不影响判断以及后续的脚本执行,觉得碍眼的话2>/dev/null把报错扔了就好。
shell脚本自动化执行jar包_第3张图片
shell脚本自动化执行jar包_第4张图片
成功执行并写入log信息。

总结

记录了自动执行jar的脚本,主要包含前置的判断和现有进程关闭,以及自动执行后台java命令两部分。整体的思路还是比较明确的,不过真写的时候要注意的还挺多,比如pid拿来的时候可能有多个等。自动化脚本还是比较方便,以后可以用来持续部署,挺好的。

你可能感兴趣的:(linux,自动化,jar,shell)