需要用shell脚本来自动化执行jar包,以后可以用jenkins来CI/CD,记录一下对应实现。
实现需求
- 以命令行执行shell传入的第一个参数为jar名进行执行。
- 对应jar已存在执行进程,关闭对应进程后再执行。
- 以后台方式执行对应的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
。
效果展示
手动启动jar程序,pid17193。
执行脚本,停止现有进程,并执行新进程17225。中间有个错误提示,因为grep pid的时候拿到的是一个类似数组的东西,直接-z
的时候会报错,不过不影响判断以及后续的脚本执行,觉得碍眼的话2>/dev/null
把报错扔了就好。
成功执行并写入log信息。文章来源:https://uudwc.com/A/vmp51
总结
记录了自动执行jar的脚本,主要包含前置的判断和现有进程关闭,以及自动执行后台java命令两部分。整体的思路还是比较明确的,不过真写的时候要注意的还挺多,比如pid拿来的时候可能有多个等。自动化脚本还是比较方便,以后可以用来持续部署,挺好的。文章来源地址https://uudwc.com/A/vmp51