shell启动脚本
一般启动启动脚本具有以下几个功能:
- 校验用户
- 定义变量
- 配置JVM参数及启动项
- 启动、停止、重启、查看状态等功能
代码
校验用户
checkUser() {
if [ "`whoami`" == "root" ]; then
echo "[Pre-Requirement]- You can't root to run this script"
exit 1
fi
}
checkUser
声明checkUser函数,并调用函数。 if 语句中通过 whoami 命令查询当前用户 单引号、双引号、反引号具体区别详情点击
定义变量
## 讲解见下方(1,2)
bin_path=`cd $(dirname $0); pwd`
APP_NAME=testAppName
BASE=$(dirname $bin_path)
conf=${BASE}/conf/application.yaml
log=${BASE}/conf/logback.xml
XMS=512m
XMX=1024m
profile=product
CLASS='com.test.ApplicationMain'
## 创建日志目录 ,讲解见(3)
if [ ! -d $BASE/logs ] ; then
mkdir -p "${BASE}/logs"
fi
if [ -z "$JAVA" ] ; then
JAVA=$(which java)
fi
if [ -z "$JAVA" ]; then
echo "[Pre-Requirement] - Cannot find a Java JDK. Please set either set JAVA or put java (>=1.8) in your PATH." 2>&2
exit 1
fi
if [[ $# -eq 2 ]]; then
profile=$2
fi
有几点需要注意的:
- 在bash shell中, {},因为在多重嵌套中反引号还需要通过反斜杠转义而$()不需要。 具体分析详见此链接
- 0) 这个命令是用来查看当前目录路径的。
%0 为当前文件的全路径(如:/tmp/bin/run.sh)
dirname 命令是用来获取当前文件的目录的路径的使用方式如下:
命令:dirname /tmp/logs/common.log
结果:/tmp/logs
- -d 是 文件存在且为目录;-z为字符串是否为空
- $ 用法
$# 参数个数
$0 当前文件路径
$1 $2 $3 第一个 第二个 第三个参数
校验程序状态
app_status() {
## 通过启动类变量${CLASS} 查询出进程;grep invert 去掉grep进程;通过awk 解析出ps结果中的第二个:进程id
pid=`ps -ef|grep ${CLASS}|grep -v grep|awk '{print $2}'`
## grep invert去掉 空字符串; wc -l 统计行数
app_wc=`echo ${pid} | grep -v ^$ | wc -l`
if [ ${app_wc} -eq 1 ]; then
if [ -z $1 ]; then
echo -e "[STATUS] - $APP_NAME $pid is running ..."
fi
return 1
elif [ ${app_wc} -gt 1 ]; then
echo -e "[STATUS] - $APP_NAME has $app_wc process is running !!!"
return 2
else
if [ -z $1 ]; then
echo -e "[STATUS] - $APP_NAME is stopped."
fi
return 0
fi
}
应用启动
java_start(){
if [[ app_status -eq 0 ]]; then
echo "[START] - $APP_NAME starting."
## -e为 isFileExist;中间的-a表示且的意思,用来连接多个条件
if [ -e ${conf} -a -e ${log} ]; then
JAVA_OPTS="-server -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5432 -XX:-OmitStackTraceInFastThrow -Xms${XMS} -Xmx${XMX} -Xloggc:${BASE}/logs/gc.log -verbose:gc -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${BASE}/logs -Duser.dir=${BASE}"
APP_OPTS="--spring.profiles.active=${profile} --spring.config.location=${conf} --logging.config=${log}"
for i in ${BASE}/lib/*;
## 通过:(冒号),拼接全部jar路径
do CLASSPATH=$i:"$CLASSPATH";
done
if [[ $1 -eq 0 ]]; then
${JAVA} ${JAVA_OPTS} -classpath .:$CLASSPATH $CLASS $APP_OPTS 1>/dev/null 2>&1 &
elif [[ $1 -eq 1 ]]; then
${JAVA} ${JAVA_OPTS} -classpath .:$CLASSPATH $CLASS $APP_OPTS
fi
## $!为后台运行的最后一个进程ID
pid=$!
## -n pid不为空
if [[ -n pid ]]; then
echo "[START] - $APP_NAME running with ${pid}"
else
echo "[START] - $APP_NAME running Fail..."
fi
else
echo '[Pre-Requirement] - Configuration file not found!!!'
fi
elif [[ app_status -eq 1 ]]; then
echo "[START] - $APP_NAME is already running."
fi
}
停止服务
app_stop() {
if [[ app_status -eq 0 ]];then
echo "[STOP] - $APP_NAME is not running."
exit
fi
echo -e "[STOP] - stopping $APP_NAME $pid ... "
[ -n "$pid" ] && kill $pid
## $?为上次命令的结果(?表示问操作系统~~)
ret=$?
waitTimes=1
while [ ${ret} = 0 -a ${waitTimes} -lt 20 ] ;do
app_status 1
app_status=$?
if [[ app_status -eq 0 ]]; then
echo -e "[STOP] - stopped app."
break
fi
sleep 1
echo -e "[STOP] - stop app ${waitTimes}th times."
((waitTimes--))
done
}