shell脚本后台启动停止jar包并且计算运行时间
源代码
#!/bin/bash
JAR_NAME=demo.jar
start() {
begin=`date +%s`
nohup java -jar "$JAR_NAME" 2>&1 &
i=0
while [ 1 ]
do
PID=$(ps -ef | grep "$JAR_NAME" | grep -v grep | awk '{print $2}')
if [[ -n $PID ]]; then
array=(${PID//\n/ })
if test $[i] -eq 0; then
echo -ne "${#array[*]} $JAR_NAME is running\r"
else
echo -ne "${#array[*]} $JAR_NAME has been running for $i seconds\r"
fi
else
end=`date +%s`
duration=$[ $end - $begin ]
echo -e "\nFinished in $duration seconds."
exit
fi
sleep 1
i=`expr $i + 1`
done
}
stop() {
PID=$(ps -ef | grep "$JAR_NAME" | grep -v grep | awk '{print $2}')
if [[ -n $PID ]]; then
for item in $PID
do
kill -9 $item
echo "kill -9 $item"
done
else
echo "$JAR_NAME not running."
fi
}
tips() {
echo "-------------------------------------"
echo ""
echo "sh $0 [commands]"
echo ""
echo "Support commands :"
echo "start -启动当前项目"
echo "stop -停止当前项目"
echo ""
echo "-------------------------------------"
}
case "$1" in
"start")
start
;;
"stop")
stop
;;
*)
tips
;;
esac
执行sh demo.sh start
启动命令:
执行 sh demo.sh stop
停止命令:
执行停止命令后:
接下来,我为大家解析一下脚本中的代码。
源码细节解析
Shell变量
定义变量:
JAR_NAME=demo.jar
注意点:不要把写C/C++/Java定义变量时留空格的习惯带到编写 shell 脚本中来。
,在JAR_NAME = demo.jar
=
前后留空格是定义 shell 变量的大忌,会抛出 JAR_NAME: command not found 这样的错误。
显然,你在 JAR_NAME 后面留空格,Bash 把它当做命令来执行,= 和 demo.jar 被看作命令的参数了。
Shell中的“switch ... case”
case ... esac 为多选择语句,与其他语言中的 switch ... case 语句类似,是一种多分支选择结构。
每个 case 分支用右圆括号开始,用两个分号;;
表示break
,即执行结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记。
case ... esac 语法格式如下:
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
如果值无法匹配模式,使用星号
*
捕获该值,再执行后面的命令。因此,我们简化一下上面的代码并保存在test.sh
中:
#!/bin/bash
case "$1" in
start)
echo start
;;
stop)
echo stop
;;
*)
echo others
;;
esac
实验结果如下,除了
sh test.sh start
和sh test.sh stop
,其他参数都会进入*
分支内。
[geekziyu@mylinuxhost ~]$ sh test.sh
others
[geekziyu@mylinuxhost ~]$ sh test.sh start
start
[geekziyu@mylinuxhost ~]$ sh test.sh stop
stop
单引号''和双引号""
看我的代码,我有时候会写单引号
''
,有时候会写双引号""
,有时候又不写。
这是不是和你们学习 javascript 或者其他语言,定义字符串的方式有些不同呢?
接下来,看一个例子,了解啥时候要加引号,啥时候不加引号?
。
#!/bin/bash
name=geekziyu
echo hello $name
echo 'hello $name'
echo "hello $name"
执行
sh test.sh
执行结果为:
hello geekziyu
hello $name
hello geekziyu
引号名称 | 引号效果 |
---|---|
单引号 | 单引号定义为所见即所得,单引号内部的内容原样输出,被单引号引起来的内容不管时变量还是常量都不会发生替换 |
双引号 | 双引号引用的内容,是先把内容中的命令、变量等解析出结果,然后再输出最终内容 |
对于本例而言,这里的双引号完全可以省略,第一条命令
echo hello $name
与第三条命令echo "hello $name"
效果一致。
echo -ne "\r"
简化一下代码量:
#!/bin/bash
JAR_NAME=demo.jar
echo -ne "$JAR_NAME is running\r"
sleep 1
echo -ne "$JAR_NAME has been running for 1 seconds\r"
sleep 1
echo -ne "\n"
效果如下图:
``和$() 用语句给变量赋值
显示地给变量直接赋值,比如 val=123
;
除此以外,还可以用语句给变量赋值:
#!/bin/bash
begin=`date +%s`
echo $begin
i=0 #输出结果例如 1653223046
i=`expr $i + 1`
echo $i #输出结果 1
了解更多 菜鸟教程 Shell 变量
了解更多 菜鸟教程 Shell 基本运算符 算数运算符 及 表达式计算工具 expr
计算数组长度 $
Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下:
array_name=(value1 value2 ... valuen)
#!/bin/bash
array=(1 2 3)
echo "数组长度等于 ${#array[*]}" # 数组长度等于 3
echo "数组长度等于 ${#array[@]}" # 数组长度等于 3
$0表示脚本文件名称
本文源码中用到了代码 echo "sh $0 [commands]"
shell内置变量 | 变量含义 | 执行脚本示例 | 变量对应值 |
---|---|---|---|
$0 |
Shell本身的文件名 | ./test.sh 1 |
test.sh |
$1~$n |
添加到Shell的各参数值。$1 是第1个参数、$2 是第2个参数… |
./test.sh 1 2 |
$1 值等于1$2 值等于2 |
分隔字符串
awk有内置的变量。对于每一个记录,即行,分隔空白字符分隔记录默认情况下,它存储在$1..$n
变量。如果该行有4个词,它会被存储在$1
,$2
,$3
,$4
。$0表示整行。
awk '{print $2}'
表示打印每一行的第二列,行与行之间肯定是用换行符\n
作为分隔符。
${parameter//pattern/string}
用 string 来替换 parameter 变量中所有匹配的 pattern。
本例中${PID//\n/ }
就是把换行符 \n
替换成为空格
。
然后,array=(${PID//\n/ })
外层的 array=(value1 value2 value3)
就是普通的数组赋值操作了。
了解更多 【shell】shell字符串分割|文件分割|剪切|截取
了解更多 Shell awk命令详解(格式+使用方法)
shell变量 字符串替换
用 string 来替换第一个匹配的pattern
${parameter/pattern/string}
从开头开始匹配 parameter 变量中的 pattern,匹配上后就用 string 来替换匹配的 pattern (仅替换第一个匹配到的 pattern)
${parameter/#pattern/string}
从结尾开始匹配 parameter 变量中的 pattern,匹配上后就用 string 替换匹配的 pattern (仅替换第一个匹配到的 pattern)
${parameter/%pattern/string}
用 string 来替换 parameter 变量中所有匹配的 pattern
${parameter//pattern/string}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)