start.sh
#!/bin/bash
tpid=`cat tpid|awk '{print $1}'`
tpid=`ps -aef|grep $tpid|awk '{print $2}'|grep $tpid`
if [ ${tpid} ];
then
echo $tpid
kill -9 $tpid
echo 'Demo is kill!'
else
rm -f tpid
touch tpid
fi
nohup java -jar demo-1.0.jar > demo.out &
echo 'Demo is started.'
echo $! > tpid
逐条解释
tpid=`cat tpid|awk '{print $1}'`
此处的tpid是一个文件,里面主要负责记录所启动的jar的进程id,也就是pid。这里是将文件tpid的第一个字段给提了出来赋给tpid这个变量。awk命令其实是将每一行的第某个字段提取出来,这里tpid文件只有一行且只有一个字段,所以该处命令就是将tpid里的内容取出来。
2.
tpid=`ps -aef|grep $tpid|awk '{print $2}'|grep $tpid`
本处的命令是:
ps -aef 将所有进程查出来,得出结果1;
grep $tpid 在结果1的基础上将涉及变量tpid的内容查出来,得出结果2;
awk ‘{print $2}’ 在结果2的基础上将每行的第二个字段提取出来,得出结果3;
grep $tpid 在结果3的基础上查找到与变量tpid一样的值更新tpid的值;
这里解释一下几个疑惑:
Q:既然有了tpid了为何还要一层层的查找?看样子为何不直接跳过这一步?
A:这样做主要是预防一次启动之后,将进程号写进了tpid这个文件之中后手动kill掉了这个进程,那么第二次启动的时候,脚本读取了文件中的字段,若是不经过这一层的校验,那么下一个if判断就会认为脚本已经被启动了。
Q:查出所有的进程后按照已有tpid查找其是否存在并获取第二个字段,这里为什么获取第二个字段?为何获取了第二个字段之后还要再grep一下?
A:用ps查看过进程信息的都知道,结果里第二个字段显示的就是进程id,至于为什么将第二个字段拿出来后要在此结果的基础上再查出tpid,是因为上一步查到的结果之中会出现grep命令也占了一个结果。
3.
if [ ${tpid} ];
then
echo $tpid
kill -9 $tpid
echo 'Demo is kill!'
判断是否不为空。若是tpid的值不为空,那么就证明该进程在运行当中,则杀死进程。
4.
if [ ${tpid} ];
then
echo $tpid
kill -9 $tpid
echo 'Demo is kill!'
判断是否不为空。若是tpid的值不为空,那么就证明该进程在运行当中,则杀死进程。
5.
else
rm -f tpid
touch tpid
若是tpid的值为空,先强制删除文件,再次创建文件。
6.
fi
nohup java -jar demo-1.0.jar > demo.out &
echo 'Demo is started.'
echo $! > tpid
以后台运行的方式启动我们的jar包,将输出指向demo.out,最后将后台运行的最后一个进程的id写进tpid之中,也就是我们上一步运行的jar的对应的进程id。
如果出现bash: ./bin/start.sh: /bin/bash^M: bad interpreter: No such file or directory请查看链接: shell脚本执行不了.
注意事项
1:脚本赋予权限 chmod +x
2:如果第一次执行脚本,出现
Usage: grep [OPTION]… PATTERN [FILE]…
Try ‘grep --help’ for more information.
Usage: grep [OPTION]… PATTERN [FILE]…
Try ‘grep --help’ for more information.
Demo is started.
错误是因为第一次没有tpid,而代码第一第二行又去查找,这个不用管。
3:出现nohup: redirecting stderr to stdout说明后台启动已完成,直接回车,查看demo.out的启动日志即可。