百度已收录
  • 在linux环境下部署任务的时候,我们正常基本操作的流程如下:
  • 用ps命令找到当前进程的pid
  • kill掉原来的pid
  • 上传新包
  • 执行启动命令
  • 启动后再次ps查看进程是否启动成功
  • 部署程序步骤繁琐
  • 并且执行完启动命令不能实时监控任务启动状态及pid,这个时候我们就需要编写一个灵活的任务启动Shell脚本

  • 新建一个任务启动脚本,这里命名为run_task

vim run_task

  • 为了有更好的视觉效果,这里采用带颜色的输出反馈,定义颜色变量
#! /bin/bash

# 定义颜色变量
# \033、\e、\E是等价的,都是转义起始符
# tput 命令会利用 terminfo 数据库中的信息,来控制和更改我们的终端,所以用tput和\033转义也是相同的效果,可以任选一种方式

# 红色
RED=$(tput setaf 1)
#RED="\033[31m"
# 绿色
GREEN=$(tput setaf 2)
#GREEN="\033[32m"
# 黄色
YELLO=$(tput setaf 3)
#YELLO="\033[33m"
# 蓝色
BLUE=$(tput setaf 4)
#BLUE="\033[34m"
# 粉色
PINK=$(tput setaf 5)
#PINK="\033[35m"
# 天蓝色
AZURE="\033[36m"
# 闪烁红
TWINKLE_RED="\033[5;31m"
# 闪烁绿
TWINKLE_GREEN="\033[5;32m"
# 清除颜色
RES=$(tput sgr0)
#RES="\033[0m"

# 测试颜色变量
echo -e "$RED 红 $RES $TWINKLE_RED 闪烁红 $RES $GREEN 绿 $RES $TWINKLE_GREEN 闪烁绿 $RES $YELLO 黄 $RES $BLUE 蓝 $RES $PINK 粉 $RES $AZURE 天蓝 $RES"
  • 退出保存

  • 给run_task加执行权限

chmod 755 run_task

  • 执行看看效果

./run_task

  • 颜色变量定义成功,接下来开始定义任务相关的变量
# 脚本程序名称,该程序为演示程序,替换为你自己的即可
binary="xxl-job-executor-sample-frameless-2.2.0-SNAPSHOT-jar-with-dependencies.jar"
# 参数
param="(start|stop|restart)"
# 日志文件名称
log_file="job-executor.log"

# 根目录,该路径为演示路径,替换为你自己的即可
base_dir=/apps/workspace/jsn-job/xxl-job-executor-samples/xxl-job-executor-sample-frameless/
# bin目录
bin_dir=$base_dir"target/"
# 日志目录,该路径为演示路径,替换为你自己的即可
log_dir=/apps/logs/xxl/
# 启动命令
cmd="java -jar 
 $bin_dir$binary
 >> $log_dir$log_file 2>&1 &"
  • 判断执行该脚本时是否有参数
#判断脚本是否有参数
if [ $# -lt 1 ]; then
    # 这里为用法提示,所以我们选用闪烁红来特别提示
    echo -e "usage: $0 $TWINKLE_RED $param $RES"
    exit -1
fi
  • 编写start函数
#启动任务函数
start()
{
    # 判断该任务进程是否已经存在
    cnt=$(ps aux | grep $binary | grep $bin_dir | grep -c $bin_dir)
    if [ $cnt != 0 ]; then
        # 这里为已经有该任务的进程存在,所以选用静态红色提示
        echo -e "$RED Instance is already running. $RES"
        return
    fi
    # 输出启动命令,选用静态黄色
    echo -e "$YELLO $cmd $RES"
    # 执行启动命令
    eval $cmd
    sleep 1

    # 检查是否启动成功
    cnt=$(ps aux | grep $binary | grep $bin_dir | grep -c $bin_dir)
    if [ $cnt == 0 ]; then
        # 这里是启动失败提示,也选用闪烁红
        echo -e "$TWINKLE_RED Fail to start $binary $RES"
        return
    fi

    # 输出任务进程号
    pid=$(ps aux | grep $binary | grep -v grep | awk '{print $2}')
    # 这里为成功启动该任务的pid号,选用静态天蓝色
    echo -e "$AZURE pid=$pid $RES"
    # 这里为成功启动的提示,选用闪烁绿
    echo -e "$TWINKLE_GREEN Started successfully $RES"
}
  • 编写stop函数
stop()
{
    # 判断是否有该任务的进程正在运行
    cnt=$(ps aux | grep $binary | grep $bin_dir | grep -c $bin_dir)
    if [ $cnt == 0 ]; then
        # 该任务还没有开始提示,选用闪烁红
        echo -e "$TWINKLE_RED $binary not started yet $RES"
        return
    fi
    # 判断是否有该任务的进程
    pid=$(ps aux | grep $binary | grep $bin_dir | grep $bin_dir | awk '{print $2}')
    if [ $pid == "" ]; then
        # 没有该任务的进程提示,选用闪烁红
        echo -e "$TWINKLE_RED No instance found $RES"
        return
    fi
    # 杀掉该任务的进程
    kill -9 $pid
    # 监控pid,直至proc下没有该任务的pid进程文件后结束
    while [ 1 ]; do
        if [ ! -e /proc/$pid ]; then
            break;
        fi
    done
    # 成功停止该任务进程提示,选用闪烁绿
    echo -e "$TWINKLE_GREEN Terminated $RES"
}
  • 编写执行流程
#判断运行该脚本参数,选择执行哪种操作
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 1
        start
        ;;
    *)
        echo -e "usage: $0 $TWINKLE_RED $param $RES"
        exit 0
esac
  • 至此,大功告成

  • 全部脚本内容如下:
#! /bin/bash

# 定义颜色变量
# \033、\e、\E是等价的,都是转义起始符
# tput 命令会利用 terminfo 数据库中的信息,来控制和更改我们的终端,所以用tput和\033转义也是相同的效果,可以任选一种方式

# 红色
RED=$(tput setaf 1)
#RED="\033[31m"
# 绿色
GREEN=$(tput setaf 2)
#GREEN="\033[32m"
# 黄色
YELLO=$(tput setaf 3)
#YELLO="\033[33m"
# 蓝色
BLUE=$(tput setaf 4)
#BLUE="\033[34m"
# 粉色
PINK=$(tput setaf 5)
#PINK="\033[35m"
# 天蓝色
AZURE="\033[36m"
# 闪烁红
TWINKLE_RED="\033[5;31m"
# 闪烁绿
TWINKLE_GREEN="\033[5;32m"
# 清除颜色
RES=$(tput sgr0)
#RES="\033[0m"

# 脚本程序名称,该程序为演示程序,替换为你自己的即可
binary="xxl-job-executor-sample-frameless-2.2.0-SNAPSHOT-jar-with-dependencies.jar"
# 参数
param="(start|stop|restart)"
# 日志文件名称
log_file="job-executor.log"

# 根目录,该路径为演示路径,替换为你自己的即可
base_dir=/apps/workspace/jsn-job/xxl-job-executor-samples/xxl-job-executor-sample-frameless/
# bin目录
bin_dir=$base_dir"target/"
# 日志目录,该路径为演示路径,替换为你自己的即可
log_dir=/apps/logs/xxl/
# 启动命令
cmd="java -jar 
 $bin_dir$binary
 >> $log_dir$log_file 2>&1 &"

#判断脚本是否有参数
if [ $# -lt 1 ]; then
    # 这里为用法提示,所以我们选用闪烁红来特别提示
    echo -e "usage: $0 $TWINKLE_RED $param $RES"
    exit -1
fi

#启动任务函数
start()
{
    # 判断该任务进程是否已经存在
    cnt=$(ps aux | grep $binary | grep $bin_dir | grep -c $bin_dir)
    if [ $cnt != 0 ]; then
        # 这里为已经有该任务的进程存在,所以选用静态红色提示
        echo -e "$RED Instance is already running. $RES"
        return
    fi
    # 输出启动命令,选用静态黄色
    echo -e "$YELLO $cmd $RES"
    # 执行启动命令
    eval $cmd
    sleep 1

    # 检查是否启动成功
    cnt=$(ps aux | grep $binary | grep $bin_dir | grep -c $bin_dir)
    if [ $cnt == 0 ]; then
        # 这里是启动失败提示,也选用闪烁红
        echo -e "$TWINKLE_RED Fail to start $binary $RES"
        return
    fi

    # 输出任务进程号
    pid=$(ps aux | grep $binary | grep -v grep | awk '{print $2}')
    # 这里为成功启动该任务的pid号,选用静态天蓝色
    echo -e "$AZURE pid=$pid $RES"
    # 这里为成功启动的提示,选用闪烁绿
    echo -e "$TWINKLE_GREEN Started successfully $RES"
}

stop()
{
    # 判断是否有该任务的进程正在运行
    cnt=$(ps aux | grep $binary | grep $bin_dir | grep -c $bin_dir)
    if [ $cnt == 0 ]; then
        # 该任务还没有开始提示,选用闪烁红
        echo -e "$TWINKLE_RED $binary not started yet $RES"
        return
    fi
    # 判断是否有该任务的进程
    pid=$(ps aux | grep $binary | grep $bin_dir | grep $bin_dir | awk '{print $2}')
    if [ $pid == "" ]; then
        # 没有该任务的进程提示,选用闪烁红
        echo -e "$TWINKLE_RED No instance found $RES"
        return
    fi
    # 杀掉该任务的进程
    kill -9 $pid
    # 监控pid,直至proc下没有该任务的pid进程文件后结束
    while [ 1 ]; do
        if [ ! -e /proc/$pid ]; then
            break;
        fi
    done
    # 成功停止该任务进程提示,选用闪烁绿
    echo -e "$TWINKLE_GREEN Terminated $RES"
}

# 判断运行该脚本参数,选择执行哪种操作
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        sleep 1
        start
        ;;
    *)
        echo -e "usage: $0 $TWINKLE_RED $param $RES"
        exit 0
esac

注:因这里讲解需要,脚本内有N多注释,如熟练以后,可将注释删除精简脚本

  • 接下来我们看看效果

    • 当运行该脚本未加参数或者加错参数时
    • 正常操作
    • 当已经有该任务的进程再调用该脚本启动时
    • 当没有该任务的进程时调用该脚本停止程序时,可以看到第一次为正常停止,第二次就给提示了
  • 一次编写,简洁明了,到处运行,逼格还高