354 lines
13 KiB
Bash
Executable File
354 lines
13 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# $0 为当前脚本文件名
|
||
PGR="$0"
|
||
|
||
# 循环判断当前脚本是否为软链接,若为软链接,则将当前脚本指向的文件路径赋值给PGR
|
||
while [ -h "$PGR" ]; do
|
||
ls=$(ls -ld "$PGR")
|
||
link=$(expr "$ls" : '.*-> \(.*\)$')
|
||
if expr "$link" : '/.*' > /dev/null; then
|
||
PGR="$link"
|
||
else
|
||
PGR=$(dirname "PGR")/"$link"
|
||
fi
|
||
done
|
||
|
||
# 获取当前脚本所在目录
|
||
PRGDIR=$(dirname "$PGR")
|
||
|
||
# -z 判断字符串是否为空
|
||
# 若BASEDIR为空,则将当前脚本所在目录的父目录赋值给BASEDIR
|
||
# exit 表示如果 cd 命令执行失败,则执行 exit 命令退出脚本
|
||
[ -z "$BASEDIR" ] && BASEDIR=$(cd "$PRGDIR/.." >/dev/null || exit; pwd)
|
||
|
||
if [ -r "$BASEDIR/bin/setenv.sh" ]; then
|
||
source "$BASEDIR"/bin/setenv.sh
|
||
# cut从文件中提取每行的第一个字段,这里使用 -d= 指定 = 号作为分隔符,-f1 表示提取第一个字段
|
||
# grep -v 过滤掉以 # 号开头的行,这些行通常是注释行, -v 表示反向选择,即选择不匹配#开头的行
|
||
export $(cut -d= -f1 "$BASEDIR/bin/setenv.sh"|grep -v '^#')
|
||
fi
|
||
|
||
if [ -z "INSTANCE_NAME" ]; then
|
||
INSTANCE_NAME=$CONFIG_INSTANCE_NAME
|
||
if [ -z "$INSTANCE_NAME" ]; then
|
||
echo "error:INSTANCE_NAME not set, Operation aborted"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$LOG_BASE_PATH" ]; then
|
||
LOG_BASE="$BASEDIR"/log
|
||
else
|
||
LOG_BASE="$LOG_BASE_PATH"/startlog
|
||
fi
|
||
|
||
|
||
# 如果不存在则创建该目录,并且创建过程中的标准错误被重定向到 /dev/null
|
||
if [ -z "$LOG_BASE" ]; then
|
||
# 先将标准输出与标准错误重定向到/dev/null,然后再将标准错误重定向到标准输出,只将错误命令进行输出到控制台
|
||
mkdir -p "$LOG_BASE" >/dev/null 2>&1
|
||
fi
|
||
# 2>&1 将标准错误重定向到标准输出,程序或命令的正常输出和错误输出就可以在标准输出中查看
|
||
# >/dev/null 2>&1 这样用的原因是: 如果命令出错,那么错误信息不会输出到/dev/null,仍然会输出屏幕上;
|
||
# 但是如果将标准错误重定向到标准输出上,那么错误信息就会随着标准输出重定向到/dev/null中
|
||
|
||
# 控制台输出为空输出
|
||
if [ -z "$CONSOLE_OUT" ]; then
|
||
CONSOLE_OUT=/dev/null
|
||
fi
|
||
|
||
if [ -z "$INSTANCE_PID" ]; then
|
||
INSTANCE_PID="$BASEDIR/bin/.pid"
|
||
fi
|
||
|
||
# 当tty是可用时, 不会输出到控制台
|
||
have_tty=0
|
||
# 当前进程是否关联到一个终端设备,如果是,have_tty设为1
|
||
if [ "$(tty)"!= "not a tty" ]; then
|
||
have_tty=1
|
||
fi
|
||
|
||
if [ -z "$UMASK" ]; then
|
||
UMASK="0027"
|
||
fi
|
||
# 设置当前shell进程的UMASK值为$UMASK。
|
||
umask $UMASK
|
||
|
||
# 重新设置 _NOHUP 变量的值,USE_NOHUP 是一个用于控制是否使用 _NOHUP 命令的开关
|
||
unset _NOHUP
|
||
if [ "$USE_NOHUP" = "true" ]; then
|
||
_NOHUP="nohup"
|
||
fi
|
||
|
||
# --------------------------------- Execute The Requested Command ----------------------------------
|
||
|
||
# 从 INSTANCE_NAME 变量的值中提取出前两个部分,并将其赋值给 CLUSTER_NAME 变量,-d 参数指定了分隔符为 _
|
||
CLUSTER_NAME=$(echo "$(INSTANCE_NAME)" | cut -f 1,2 -d '_')
|
||
|
||
showHelp() {
|
||
echo "Usage: bootstrap.sh ( command ... )"
|
||
echo "commands:"
|
||
echo " start Start Instance ${INSTANCE_NAME} in a separate window"
|
||
echo " debug Start Instance ${INSTANCE_NAME} in a separate window with debug"
|
||
echo " restart Restart Instance ${INSTANCE_NAME} in a separate window"
|
||
echo " stop Stop Instance ${INSTANCE_NAME}, waiting up to 5 seconds for the process to end"
|
||
echo " stop n Stop Instance ${INSTANCE_NAME}, waiting up to n seconds for the process to end"
|
||
echo " stop -force Stop Instance ${INSTANCE_NAME}, waiting up to 5 seconds and then use kill -KILL if still running"
|
||
echo " stop n -force Stop Instance ${INSTANCE_NAME}, waiting up to n seconds and then use kill -KILL if still running"
|
||
echo "Note: Waiting for the process to end and use of the -force option require that \$INSTANCE_PID is defined."
|
||
}
|
||
|
||
startInstance() {
|
||
# $@ 表示传递给脚本的所有参数,并赋值给 APP_ARGUMENTS 变量
|
||
APP_ARGUMENTS="$APP_ARGUMENTS $@"
|
||
START_COMMON="START_COMMON $APP_ARGUMENTS"
|
||
|
||
echo "Start instance: $INSTANCE_NAME"
|
||
echo "Start common: $START_COMMON"
|
||
# -n 选项表示不输出换行符,-e 选项表示解释转义字符
|
||
echo -ne "start instance ......"
|
||
|
||
# -z 检查字符串是否为空,不为空进入
|
||
if [ ! -z "$INSTANCE_PID" ]; then
|
||
# -f 选项表示检查文件是否存在,存在进入
|
||
if [ -f "$INSTANCE_PID" ]; then
|
||
# -s 选项表示检查文件是否为空,不为空进入
|
||
if [ -s "$INSTANCE_PID" ]; then
|
||
echo "Exiting PID file found during start."
|
||
# -r 选项表示检查文件是否可读,可读进入
|
||
if [ -r "$INSTANCE_PID" ]; then
|
||
# 读取 INSTANCE_PID 文件中的内容,并赋值给 PID 变量
|
||
PID=$(cat "$INSTANCE_PID")
|
||
# 使用 ps 命令检查进程是否存在,-p 选项指定进程号,>/dev/null 2>&1
|
||
ps -p "$PID" >/dev/null 2>&1
|
||
# 如果进程存在,获取实际实例进程的进程号, $?表示上一个命令的退出状态码
|
||
if [ $? -eq 0 ]; then
|
||
#
|
||
PID_INS=$(ps -ef|grep "${PID_CHECK_FLAG}"|grep -v grep| grep -v 'bootstarp.sh' | awk '{print $2}'|head -n 1)
|
||
if [ "$PID_INS" = "" ]; then
|
||
echo "$INSTANCE_NAME not is running!"
|
||
echo "Force removing/clearing stale pid file."
|
||
rm -rf "$INSTANCE_PID" >/dev/null 2>&1
|
||
if [ $? != 0 ]; then
|
||
if [ ! -w "$INSTANCE_PID" ]; then
|
||
echo "warning:Unable to remove or write to empty PID file.Start aborted."
|
||
exit 1
|
||
fi
|
||
fi
|
||
else
|
||
echo "INSTANCE $INSTANCE_NAME to still be running with PID $PID.Start aborted."
|
||
echo "If the following process is not a INSTANCE $INSTANCE_NAME process, remove the PID file and try again:"
|
||
ps -f -p "$PID"
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "Removing/clearing stale pid file."
|
||
rm -rf "$INSTANCE_PID" >/dev/null 2>&1
|
||
if [ $? != 0 ]; then
|
||
if [ -w "$INSTANCE_PID" ]; then
|
||
# 清空文件内容
|
||
cat /dev/null > "$INSTANCE_PID"
|
||
else
|
||
echo "warning:Unable to remove or write to empty PID file.Start aborted."
|
||
exit 1
|
||
fi
|
||
fi
|
||
fi
|
||
else
|
||
echo "warning:Unable to read PID file.Start aborted."
|
||
exit 1
|
||
fi
|
||
else
|
||
rm -f "$INSTANCE_PID" >/dev/null 2>&1
|
||
if [ $? != 0 ]; then
|
||
if [ ! -w "$INSTANCE_PID" ]; then
|
||
echo "warning:Unable to remove or write to empty PID file.Start aborted."
|
||
exit 1
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
shift # 移除传递给脚本的第一个参数
|
||
eval "$START_COMMON" # 恢复原先初始的命令
|
||
|
||
SLEEP=10
|
||
# -gt表示大于的意思
|
||
while [ $SLEEP -gt 0 ]; do
|
||
echo -ne "."
|
||
sleep 1
|
||
|
||
SLEEP=$(expr "$SLEEP" - 1)
|
||
done
|
||
|
||
PID=$(ps -ef|grep "${PID_CHECK_FLAG}"|grep -v grep| grep -v 'bootstarp.sh' | awk '{print $2}'|head -n 1)
|
||
if [ ! -z "INSTANCE_PID" ]; then
|
||
echo "$PID" > "$INSTANCE_PID"
|
||
fi
|
||
|
||
SLEEP=30
|
||
while [ $SLEEP -gt 0 ]; do
|
||
echo -ne "."
|
||
sleep 1
|
||
# 检查进程是否存在 -0 表示检查进程是否存在,$? 表示上一个命令的退出状态码
|
||
kill -0 "$PID" >/dev/null 2>&1
|
||
if [ $? -ne 0 ]; then
|
||
echo -ne "\n"
|
||
echo "warning:Instance $INSTANCE_NAME exit. start failed"
|
||
exit 1
|
||
fi
|
||
|
||
#LN=$(netstat -ntlp --numeric-ports 2>/dev/null|grep LISTEN|grep "$PID")
|
||
LN=$(ss -np 2>/dev/null|grep 6379|grep "$PID")
|
||
if [ -z "$LN" ]; then
|
||
echo -ne "\n"
|
||
echo "INSTANCE $INSTANCE_NAME with PID: $PID is running, start success"
|
||
return
|
||
fi
|
||
|
||
SLEEP=$(expr "$SLEEP" - 1)
|
||
done
|
||
}
|
||
|
||
|
||
|
||
stopInstance(){
|
||
echo "stop instance ......"
|
||
SLEEP=45
|
||
KILL_SLEEP_INTERVAL=5
|
||
if [ ! -z "$1" ]; then
|
||
echo $1 | grep "[^0-9]" >/dev/null 2>&1
|
||
if [ $? -gt 0]; then
|
||
SLEEP=$1
|
||
fi
|
||
fi
|
||
shift
|
||
FORCE=0
|
||
if [ "$1" = "-force" ]; then
|
||
shift
|
||
FORCE=1
|
||
fi
|
||
|
||
PID=""
|
||
if [ ! -z "$INSTANCE_PID" ]; then
|
||
# -f 选项表示检查文件是否存在,存在进入
|
||
if [ -f "$INSTANCE_PID" ]; then
|
||
# -s 选项表示检查文件是否为空,不为空进入
|
||
if [ -s "$INSTANCE_PID" ]; then
|
||
if [ -r "$INSTANCE_PID"]; then
|
||
PID=$(cat "$INSTANCE_PID")
|
||
PID_INS=$(ps -ef|grep "${PID_CHECK_FLAG}"|grep -v grep| grep -v 'bootstarp.sh' | awk '{print $2}'|head -n1)
|
||
# 实际进程为空,清除
|
||
if [ "$PID_INS" = "" ]; then
|
||
echo "$INSTANCE_NAME not is running! Stop will not execute! The real pid info will print!"
|
||
rm -rf "$INSTANCE_PID" >/dev/null 2>&1
|
||
if [ $? -ne 0 ]; then
|
||
if [ ! -w "$INSTANCE_PID" ]; then
|
||
echo "warning:Unable to remove or write to empty PID file.Start aborted."
|
||
exit 1
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
kill -0 "$PID" >/dev/null 2>&1
|
||
if [ $? -gt 0 ]; then
|
||
PID=$(ps -ef|grep "${PID_CHECK_FLAG}"|grep -v grep| grep -v 'bootstarp.sh' | awk '{print $2}'|head -n1)
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$PID" ]; then
|
||
PID=$(ps -ef|grep "${PID_CHECK_FLAG}"|grep -v grep| awk '{print $2}'|head -n1)
|
||
fi
|
||
|
||
if [ -z "$PID" ]; then
|
||
echo "Instance no process found"
|
||
echo "Instance stopped."
|
||
exit 0
|
||
fi
|
||
|
||
echo "Attempting to signal the process to stop throught OS signal."
|
||
kill -15 $PID >/dev/null 2>&1
|
||
if [ $FORCE -eq 0 ]; then
|
||
while [ $SLEEP -gt 0 ]; do
|
||
kill -0 $PID >/dev/null 2>&1
|
||
if [ $? -gt 0 ]; then
|
||
rm -f "INSTANCE_PID" >/dev/null 2>&1
|
||
if [ $? -gt 0 ]; then
|
||
if [ -w "$INSTANCE_PID" ]; then
|
||
cat /dev/null > "$INSTANCE_PID"
|
||
FORCE=0
|
||
else
|
||
echo "info:The PID file could not be removed or cleared."
|
||
fi
|
||
fi
|
||
echo "Instance stopped."
|
||
break
|
||
fi
|
||
if [ $SLEEP -gt 0 ]; then
|
||
sleep 1
|
||
fi
|
||
if [ $SLEEP -eq 0 ]; then
|
||
echo "Instance did not stop in time."
|
||
if [ $FORCE -eq 0 ]; then
|
||
echo "warning:PID file was not removed."
|
||
fi
|
||
echo "To aid diagnostics a thread dump has been written to standard out."
|
||
kill -3 $PID >/dev/null 2>&1
|
||
fi
|
||
SLEEP=$(expr "$SLEEP" - 1)
|
||
done
|
||
elif [ $FORCE -eq 1 ]; then
|
||
sleep 2
|
||
echo "warning:Killing Instance with the PID: $PID"
|
||
kill -9 $PID >/dev/null 2>&1
|
||
while [ $KILL_SLEEP_INTERVAL -ge 0 ]; do
|
||
kill -0 $PID >/dev/null 2>&1
|
||
if [ $? -gt 0 ]; then
|
||
rm -f "$INSTANCE_PID" >/dev/null 2>&1
|
||
if [ $? -gt 0 ]; then
|
||
if [ -w "$INSTANCE_PID" ]; then
|
||
cat /dev/null > "$INSTANCE_PID"
|
||
else
|
||
echo "info:The PID file could not be removed."
|
||
fi
|
||
fi
|
||
echo "warning:The Instance process has been killed."
|
||
break
|
||
fi
|
||
if [ $KILL_SLEEP_INTERVAL -gt 0 ]; then
|
||
sleep 1
|
||
fi
|
||
$KILL_SLEEP_INTERVAL=$(expr "$KILL_SLEEP_INTERVAL" - 1)
|
||
done
|
||
if [ $KILL_SLEEP_INTERVAL -lt 0 ]; then
|
||
echo "warning:Instance has not been killed completey yet."
|
||
fi
|
||
fi
|
||
}
|
||
|
||
if [ "$1" = "start" ]; then
|
||
shift
|
||
startInstance "$@"
|
||
elif [ "$1" = "stop" ]; then
|
||
shift
|
||
stopInstance $1 $2
|
||
elif [ "$1" = "restart" ]; then
|
||
shift
|
||
stopInstance "$@"
|
||
startInstance "$@"
|
||
elif [ "$1" = "debug" ]; then
|
||
shift
|
||
startInstance "$@"
|
||
else
|
||
showHelp
|
||
fi
|
||
|
||
|
||
|
||
|
||
|