从事Java开发的程序员应该知道,我们用SpringBoot开发完的程序,最终都是要上线的,也有的是私人用的,不管怎么样,它总是要被部署到一台服务器当中的,而服务器百分之99都是Linux系统,但是我们在Linux中一行一行去敲命令,首先太繁琐,容易敲错,而且不好管理程序,于是我们可以编写Shell脚本去启停和管理程序。
脚本
#!/bin/bash
# 定义变量
# 要运行的jar包路径,加不加引号都行。
# 注意:等号两边 不能 有空格,否则会提示command找不到
JAR_NAME="这里填写你的jar包地址"
# 如果输入格式不对,给出提示!
tips() {
echo ""
echo "WARNING!!!......Tips, please use command: sh xxx.sh [start|stop|restart|status]. For example: sh xxx.sh start "
echo ""
exit 1
}
# 启动方法
start() {
# 重新获取一下pid,因为其它操作如stop会导致pid的状态更新
pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`
# -z 表示如果$pid为空时执行
if [ -z $pid ]; then
# 不挂断启动jar程序,标准和错误信息输出到 /mydata/logs/app.log 中
nohup java -jar $JAR_NAME > /mydata/logs/app.log 2>&1 &
pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`
echo ""
echo "Service ${JAR_NAME} is starting!pid=${pid}"
echo "........................Here is the log.............................."
echo "....................................................................."
echo "........................Start successfully!........................."
else
echo ""
echo "Service ${JAR_NAME} is already running,it's pid = ${pid}. If necessary, please use command: sh xxx.sh restart."
echo ""
fi
}
# 停止方法
stop() {
# 重新获取一下pid,因为其它操作如start会导致pid的状态更新
pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`
# -z 表示如果$pid为空时执行。 注意:每个命令和变量之间一定要前后加空格,否则会提示command找不到
if [ -z $pid ]; then
echo ""
echo "Service ${JAR_NAME} is not running! It's not necessary to stop it!"
echo ""
else
kill -9 $pid
echo ""
echo "Service stop successfully!pid:${pid} which has been killed forcibly!"
echo ""
fi
}
# 输出运行状态方法
status() {
# 重新获取一下pid,因为其它操作如stop、restart、start等会导致pid的状态更新
pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`
# -z 表示如果$pid为空时执行。注意:每个命令和变量之间一定要前后加空格,否则会提示command找不到
if [ -z $pid ];then
echo ""
echo "Service ${JAR_NAME} is not running!"
echo ""
else
echo ""
echo "Service ${JAR_NAME} is running. It's pid=${pid}"
echo ""
fi
}
# 重启方法
restart() {
echo ""
echo ".............................Restarting.............................."
echo "....................................................................."
# 重新获取一下pid,因为其它操作如start会导致pid的状态更新
pid=`ps -ef | grep $JAR_NAME | grep -v grep | awk '{print $2}'`
# -z 表示如果$pid为空时执行。 注意:每个命令和变量之间一定要前后加空格,否则会提示command找不到
if [ ! -z $pid ]; then
kill -9 $pid
fi
start
echo "....................Restart successfully!..........................."
}
# 根据输入参数执行对应方法,不输入则执行tips提示方法
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
tips
;;
esac
使用
启动Jar程序:sh xxx.sh start
停止Jar程序:sh xxx.sh stop
重启Jar程序:sh xxx.sh restart
查看程序状态:sh xxx.sh status
分析
一般情况下运行jar包,当前是可运行的jar包,我们可以直接使用命令
java -jar xxx.jar
按下ctrl+C ,关闭当前 ssh 或者直接关闭窗口,当前程序都会退出
我们在命令的结尾添加 “&” ,&表示该程序可以在后台执行
java -jar xxx.jar &
但是在当窗口关闭时,程序也会中止运行
命令最前面加个 nohup
关键字,这样程序就会不挂断运行命令,当ssh终端关闭时,程序仍然在运行,当前程序的日志会被写入到当前目录的 nohup.out
文件中
nohup java -jar xxx.jar &
我们可以改下输入的日志文件
# 当前程序的日志会被写入到当前目录的 log.out 文件中
nohup java -jar xxx.jar > log.out &
# 如果不想写日志,可以将日志重定向到 /dev/null 中
# /dev/null代表linux的空设备文件,所有往这个文件里面写入的内容都会丢失
# 标准输出就会不再存在,没有任何地方能够找到输出的内容
nohup java -jar xxx.jar > /dev/null &
# 标准输出(stdout)重定向到 /dev/null 中(丢弃标准输出)
# 然后标准错误输出(stderror)由于重用了标准输出的描述符
# 所以标准错误输出也被定向到了 /dev/null 中,错误输出同样也被丢弃了
# 标准输出重定向到log.out中,然后错误输出由于重用了标准输出的描述符,所以错误输出也被定向到了log.out中
nohup java -jar xxx.jar >log.out 2>&1 &
# 其中关于关于2>&1的含义是:
# 将标准错误输出重定向到标准输出
# 符号>&是一个整体
但是不管哪种情况,如果日志输出,日志文件都会增加很快,造成单个文件很大。
所以需要拆分文件:
1:定时作业,每天将日志文件复制一份,然后将当前的日志文件清空
2:借助 cronolog来分隔日志
nohup java -jar xxx.jar | /usr/local/cronolog/sbin/cronolog logs/console-%Y-%m-%d.out &
这样每天会产生一个console开头的日志文件。
如果我们想要查看日志信息,可以使用以下命令:
# 实时查看日志后100行
tailf -100 xxx.log
问题
之前我在Windows系统的编辑器中编写好Shell脚本后,然后将其直接上传到Linux服务器中,但是运行时直接报错了。
syntax error near unexpected token `$'\r'
内心一万个WTF,为啥不行呢,其实是在Windows编写的时候换行符也搞过来了,两个系统并不适配。
第一步
vim -b xxx.sh
# 或者
vi -b xxx.sh
我ca,果然如此,在复制进来后,怎么每行后面都多了 ^M
这个玩意!!!
第二步
sed -i 's/\r//g' xxx.sh
大功告成,搞定了。
评论区