shell将java,node程序打包成docker,并且发布到服务器

/ dockerLinux / 没有评论 / 2031浏览

java_docker.sh

#!/bin/bash

#English help:
#The java written by yanzuoguang@qq.com is packaged and published to the docker help document. Syntax format:
#./java_docker.sh
#  [--log] : Turn on the log information display of this shell document, and the global variables and extension information will be displayed for this debugging and editing mode.
#  [--help] : display help information.
#  [--c] : After execution, temporary files are not deleted.
#  [--l en|ch ] : Set Shell language,default as ch. En = English, ch = Chinese
#  [--sh] : Set the current script directory as the execution directory.
#  [--t temp_folder_path] : Set the temporary directory of shell to cache intermediate files, which will be deleted after execution.
#  [-mcc] : Maven off switch will turn off Maven packaging after setting.
#  [-mc maven_command] : Customize the Maven packaging command. The default command is MVN clean package.
#  [-dcc] : The docker off switch will turn off docker packaging after setting.
#  [-da author] : Docker author settings, used to generate dockerfile files.
#  [-dp expose] : Docker port setting, used to generate dockerfile file.
#  [-ssh user@ip]: The server address of the SSH that docker needs to publish to.
#  [-ssp ssh_port] : The server port of the SSH to which docker needs to be published. The default value is ''
#  [-jp jar_path]: The path of the jar package, relative to the start of the script.
#  [-jm java_memory_arguments] : When docker is packaged, set the JAVA memory parameter information. The default value is'-Xms200m'
#  [-ja jar_arguments] : When docker is packing, set the execution related parameters of jar package. The default value is ''
#  [-sh shell] : Shell commands to be executed after docker is published.
#eg:
#  ./java_docker.sh --help --l en
#  ./java_docker.sh
#  ./java_docker.sh -mc "mvn clean package deploy"
#  ./java_docker.sh -jm "-Xms200m -Xmx3000m" -ja "--spring.profiles.active=prod --yzg.config.url=/home/tbd_pd/conf/tbd_reg.properties"
#  ./java_docker.sh -ssh root@l206 -ssp 22
#normal usage:
#  1.On the docker target server, first create the docker network with the command:
#    docker network create --gateway=192.168.100.1 --subnet=192.168.100.0/24 evndm
#  2.Pack the current directory, force to close the docker service, and start a new docker service:
#    ./java_docker.sh -ssh root@l88 -dp "6888" -jm "-Xms200m" -sh "docker rm -f tbd-gateway;docker run -it -d  -p 6888:6888 --net evndm --ip 192.168.100.4 --restart always --name tbd-gateway tbd-gateway:latest"

#中文帮助:
#yanzuoguang@qq.com编写的java打包并且发布到docker帮助文档,语法格式:
#./java_docker.sh
#  [--log] : 开启本shell文档的日志信息显示,会显示全局变量以及扩展信息,用于本调试编辑模式.
#  [--help] : 显示帮助信息.
#  [--c] : 执行完成后,不删除临时文件.
#  [--l en|ch ] : 设置Shell语言,默认ch.en=英语,ch=中文.
#  [--sh] : 设置当前脚本目录为执行目录。
#  [--t temp_folder_path] : 设置Shell的临时目录,用于缓存中间文件,在执行完成后会被删除.
#  [-mcc] : maven关闭开关,在设置后将会关闭maven打包.
#  [-mc maven_command] : 自定义maven打包命令,默认命令为: mvn clean package.
#  [-dcc] : docker关闭开关,在设置后将会关闭docker打包.
#  [-da author] : docker作者设置,用于生成dockerfile文件.
#  [-dp expose] : docker端口设置,用于生成dockerfile文件.
#  [-ssh user@ip]: Docker需要发布到的ssh的服务器地址.
#  [-ssp ssh_port] : Docker需要发布到的ssh的服务器端口,默认为:''
#  [-jp jar_path]: jar包所在的路径,相对于脚本开始.
#  [-jm java_memory_arguments] : Docker打包时,设置Java的内存参数相关信息,默认为:'-Xms200m'
#  [-ja jar_arguments] : Docker打包时,设置Jar包的执行相关参数,默认为:''
#  [-sh shell] : docker发布后,需要执行的shell命令.
#例子:
#  ./java_docker.sh --help --l en
#  ./java_docker.sh
#  ./java_docker.sh -mc "mvn clean package deploy"
#  ./java_docker.sh -jm "-Xms200m -Xmx3000m" -ja "--spring.profiles.active=prod --yzg.config.url=/home/tbd_pd/conf/tbd_reg.properties"
#  ./java_docker.sh -ssh root@l206 -ssp 22
#通常用法:
#  1.在docker目标服务器上,先用命令创建docker网络:
#    docker network create --gateway=192.168.100.1 --subnet=192.168.100.0/24 evndm
#  2.打包当前目录,强制关闭docker服务,并且启动新的docker服务:
#    ./java_docker.sh -ssh root@l88 -dp "6888" -jm "-Xms200m" -sh "docker rm -f tbd-gateway;docker run -it -d  -p 6888:6888 --net evndm --ip 192.168.100.4 --restart always --name tbd-gateway tbd-gateway:latest"

function getTimeName(){
    local current=`date "+%Y%m%d%H%M%S"`
    echo $current;
    return $?;
}

# 显示当期时间搓
function getTime(){
    local current=`date "+%Y-%m-%d %H:%M:%S"`
    local timeStamp=`date -d "$current" +%s`
    #将current转换为时间戳,精确到毫秒,下面这个10#代表10进制来实现
    local currentTimeStamp=$((timeStamp*1000+10#`date "+%N"`/1000000))
    echo $currentTimeStamp;
    return $?;
}

# ------------------------------脚本本身相关参数-------------------------------------
# 是否开启日志
LOG=0
# 是否开启help标记,具体帮助信息请参数help信息
HELP_FLAG=0;
# 不清徐临时文件
NOT_CLEAR=0;
# 语言版本
LANGUAGE="ch";
# 用当前shell脚本的目录作为基础目录
SH_PATH=0

# ------------------------------maven相关参数---------------------------------------
# 是否开启maven打包
MAVEN_NOT_FLAG=0;
MAVEN_COMMAND='';

# ------------------------------ssh相关参数-----------------------------------------
# 是否开启ssh,以及ssh的服务器
SSH_FLAG=0;
SSH_SERVER="";
# ssh端口,默认22
SSH_PORT="22";

# ------------------------------java命令相关参数-------------------------------------
# jar包相对当前包的路径,可以通过-jp参数指定
JAR_PATH="./target/";
# java内存参数
JAVA_MEMORY="-Xms200m";
# java参数
JAVA_ARGUMENTS='';

# ------------------------------dockerfile相关参数-------------------------------------
# Docker打包标记
DOCKER_CLOSE_FLAG=0;
# 作者
AUTHOR="yanzuoguang yanzuoguang@qq.com";
# 暴露的端口
EXPOSE="20 80";

# ------------------------------docker运行相关参数-------------------------------------
# 先运行docker image后停止, 先启动后停止=1, 先停止后运行=0
# RUN_FRONT=0;

# 需要执行的命令
SHELL_COMMAND="";

# ------------------------------临时处理相关参数,shell内部变量--------------------------
# 服务器上临时路径,假如是远程,则是远程目录的临时路径
TEMP_PATH="/tmp/yanzuoguang/$(getTime)/";
# 当前脚本名称
SHELL_NAME='';
# dockerfile临时文件名
TEMP_DOCKERFILE='Dockerfile.tmp';

function language(){
    if [ $LANGUAGE = "ch" -a -n "$2" ];then
        # eval "print -- '$2'"
        echo "$2"
    else
        # eval "print -- '$1'"
        echo "$1"
    fi;
    return $?;
}

## 获取当前目录函数
function getCurrent(){
    # 获取当前脚本目录
    local currDir="$(dirname $0);"
    # 去掉最后的符号,并且显示出来
    echo ${currDir%?};
    # 返回当前函数的最后一条命令的执行状态
    return $?;
}

## 进入当前脚本目录
function goCurrent(){
    local nowPath=$(getCurrent);
    # 进入当前目录
    goPath $nowPath;
}

## 获取当前命令运行目录
function getCurrentCommand(){
    # 当前脚本目录
    pwd;
    # 返回当前函数的最后一条命令的执行状态
    return $?;
}

## 打印全局变量的值
function logGrobleVar(){
    if [ $LOG = 1 ];then
        for i in "$@"; do
            printf -- "$i:";
            eval 'printf -- "$'$i'\t"';
        done
        printf -- "\n";
    fi;
    return $?;
}

# 用于判断是否存在参数名称,调用方法为: getPara "-t" "$@" , 存在则会返回1,不存在返回0
# isPara "-a" "$@";
# isPara "-b" "$@";
function isPara(){
    local find=0;
    for i in "$@"; do
        #判断字符串是否相等,相等则变量+1
        if [ "$i" = "$1" ];then
        ((find=find+1))
        # echo $find;
        fi
        # 获取非第一个变量的值
        if [ $find = 2 ];then
        # 返回1表示包含该参数
        echo 1;
        return $?;
        fi
    done
    # 返回0表示不包含该参数
    echo 0
    return $?;
}

# 日志打印函数,在开启日志模式时生效
function log(){
    if [ $LOG = 1 ];then
        # 显示找到参数的下一个参数值
        language "$@";
    fi
}

# 用于获取当前参数的值,调用方法为: getPara "-t" "$@" , 存在则返回值,否则返回空
# a=$(getPara "-a" "$@");
# b=$(getPara "-b" "$@");
function getPara(){
    local find=0;
    for i in "$@"; do
        # 获取非第一个变量的值,等于1时表示需要找到的变量,等于2表示找到该变量的值
        if [ $find = 2 ];then
            # 显示找到参数的下一个参数值
            if [[ $i == -* ]];
            then
                break;
            else
                echo $i;
            fi;
        fi
        #判断字符串是否相等,相等则变量+1
        if [ "$i" = "$1" ];then
            # 找到次数+1
            ((find=find+1))
            # echo $find;
        fi
    done
    return $?;
}
# 用于获取当前参数的值,调用方法为: getPara "-t" "$@" , 存在则返回值,否则返回空
# a=$(getPara "-a" "$@");
# b=$(getPara "-b" "$@");
function getParaFirst(){
    local find=0;
    for i in "$@"; do
        # 获取非第一个变量的值,等于1时表示需要找到的变量,等于2表示找到该变量的值
        if [ $find = 2 ];then
            echo $i;
            break;
        fi
        #判断字符串是否相等,相等则变量+1
        if [ "$i" = "$1" ];then
            # 找到次数+1
            ((find=find+1))
            # echo $find;
        fi
    done
    return $?;
}

# 获取第一个不为空的参数
function getDefaultPara(){
    for i in "$@"; do
    if [ -z "$i" ]; then
        # echo "STRING is empty"
        continue;
    else
        echo $i;
        break;
        # echo "STRING is not empty"
    fi
    done
    return $?;
}

# 执行本地命令
function localCommand(){
    # 获取需要执行的命令行
    local COMMAND=$1;
    # 将命令行的分割符替换成换行符
    local COMMAND_LINE=$(echo "$COMMAND"|tr ";" "\n");
    # 输出命令行到循环读取
    echo "$COMMAND_LINE"|while read -r i; do
        echo "\$ $i";
        ${i};
    done

    return $?;
}

# 执行ssh命令
function sshCommand(){
    local COMMAND=$1;

    # 检测ssh命令是否存在
    _=$(command -v ssh);
    if [ "$?" != "0" ]; then
        printf -- 'You don'\''t seem to have ssh installed.\n';
        printf -- 'Get it: yum -y install ssh \n';
        printf -- 'Exiting with code 127...\n';
        exit 127;
    fi;

    echo ssh -p $SSH_PORT $SSH_SERVER "$COMMAND;exit";
    ssh -p $SSH_PORT $SSH_SERVER "$COMMAND;exit";
    return $?;
}

# sshCopy
function sshCopy(){
    local LOCAL_PATH=$1;
    local SERVER_PATH=$2;
    local ARGS=$3;

    # 检测ssh命令是否存在
    _=$(command -v scp);
    if [ "$?" != "0" ]; then
        printf -- 'You don'\''t seem to have ssh installed.\n';
        printf -- 'Get it: yum -y install ssh \n';
        printf -- 'Exiting with code 127...\n';
        exit 127;
    fi;

    echo scp $ARGS $LOCAL_PATH $SSH_SERVER:$SERVER_PATH;
    scp $ARGS $LOCAL_PATH $SSH_SERVER:$SERVER_PATH;
    return $?;
}

# 显示当前目录
function displayPath(){
    log "now path:$(pwd)" "当前路径:$(pwd)";
}

# 进入到指定目录
function goPath(){
    log "Access path: $1" "进入路径:$1";
    # 进入到指定目录
    cd $1;
    # 显示当前路径
    displayPath;
    return $?;
}

# 获取文件名
function getFileName(){
    echo ${1##*/};
    return $?;
}

# 获取不带后缀的文件名
function getFileNameNotExt(){
    local tmp=${1##*/};
    echo ${tmp%.*};
    return $?;
}

# 检测maven命令是否安装
function checkMavenCommand(){
    _=$(command -v mvn);
    if [ "$?" != "0" ]; then
        printf -- 'You don'\''t seem to have maven installed.\n';
        printf -- 'Get it: https://www.docker.com/community-edition\n';
        printf -- 'Exiting with code 127...\n';
        exit 127;
    fi;
}

# maven 打包成jar包
function mavenPackage(){
    language "In Maven packaging, the command is:" "maven打包中,命令为:" ;
    # 判断是否自定义maven命令
    if [ -n "$MAVEN_COMMAND" ]; then
        localCommand "$MAVEN_COMMAND";
    else
        checkMavenCommand;
        echo mvn clean package;
        mvn clean package;
    fi;
}
# 找到jar文件,相对当前目录
function findJar(){
    for name in `find $1 -name *.jar`
    do
    echo $name
    done
    return $?;
}

# 在临时目录中编写dockerfile文件
function releaseDockerfile(){
    local JAR_PATH=$1;

    # 生成临时dockerfile文件
    echo 'release dockerfile temp...';

    echo 'FROM java:8' > $TEMP_DOCKERFILE
    echo 'MAINTAINER '$AUTHOR >> $TEMP_DOCKERFILE
    echo 'COPY "./'${JAR_PATH##*/}'" "/home/java/"' >> $TEMP_DOCKERFILE
    if [ -z "$i" ]; then
        echo 'EXPOSE '$EXPOSE >> $TEMP_DOCKERFILE
    fi;
    # echo 'CMD ["mkdir","/home/java/conf/"]' >> $TEMP_DOCKERFILE
    # echo 'VOLUME ["/home/java/conf/"]' >> $TEMP_DOCKERFILE
    # 指定容器启动时,需要执行的命令(运行该jar程序)
    echo 'ENTRYPOINT ["java","-jar","'$JAVA_MEMORY'","/home/java/'${JAR_PATH##*/}'","'$JAVA_ARGUMENTS'"]' >> $TEMP_DOCKERFILE

    return $?;
}

# 删除临时目录中的dockerfile文件
function removeDockerfile(){
    # 删除临时dockerfile
    echo 'remove temp dockerfile';
    rm -rf $TEMP_DOCKERFILE
}

# 复制jar包到临时目录中
function copyFile(){
    local JAR_PATH=$1;
    removeFile;

    if [ $SSH_FLAG = 1 ];then
        echo "mkdir temp path $TEMP_PATH";
        sshCommand "mkdir -p $TEMP_PATH"

        # 将本地文件复制到远程目录
        echo "copy $JAR_PATH to temp path $SSH_SERVER:$TEMP_PATH$(getFileName $JAR_PATH)."
        sshCopy "$JAR_PATH" "$TEMP_PATH$(getFileName $JAR_PATH)"

        echo "copy $TEMP_DOCKERFILE to temp path $SSH_SERVER:$TEMP_PATH$(getFileNameNotExt $TEMP_DOCKERFILE).";
        sshCopy "$TEMP_DOCKERFILE" "$TEMP_PATH$(getFileNameNotExt $TEMP_DOCKERFILE)"
    else
        echo "mkdir temp path $TEMP_PATH";
        mkdir -p $TEMP_PATH

        echo "copy $JAR_PATH  to temp path $TEMP_PATH$(getFileName $JAR_PATH)."
        cp "$JAR_PATH" "$TEMP_PATH$(getFileName $JAR_PATH)"

        echo "copy $TEMP_DOCKERFILE to temp path $TEMP_PATH$(getFileNameNotExt $TEMP_DOCKERFILE).";
        cp "$TEMP_DOCKERFILE" "$TEMP_PATH$(getFileNameNotExt $TEMP_DOCKERFILE)"
    fi;

    return $?;
}

# 删除复制到的目录中的文件
function removeFile(){
    if [ $SSH_FLAG = 1 ];then
        echo "remove ssh $SSH_SERVER:$TEMP_PATH to temp path..."
        sshCommand "rm -rf '$TEMP_PATH'";
    else
        echo "remove local $TEMP_PATH temp path..."
        rm -rf "$TEMP_PATH";
    fi;
    return $?;
}

# 检测docker命令是否安装
function checkDockerCommand(){
    _=$(command -v docker);
    if [ "$?" != "0" ]; then
      printf -- 'You don'\''t seem to have Docker installed.\n';
      printf -- 'Get it: https://www.docker.com/community-edition\n';
      printf -- 'Exiting with code 127...\n';
      exit 127;
    fi;
}

# 生成镜像文件
function releaseImage(){
    local JAR_PATH=$1;
    local timeName="$(getTimeName)";
    local imageVersionName="$(getFileNameNotExt $JAR_PATH):v$timeName";
    local imageLatestName="$(getFileNameNotExt $JAR_PATH):latest";
    if [ $SSH_FLAG = 1 ];then
        echo "release ssh docker image $imageVersionName and $imageLatestName"
        sshCommand "sudo docker build -t $imageVersionName $TEMP_PATH;sudo docker tag $imageVersionName $imageLatestName"
    else
        checkDockerCommand;

        echo "release local docker image $imageVersionName and $imageLatestName "
        echo sudo docker build -t $imageVersionName $TEMP_PATH
        sudo docker build -t $imageVersionName $TEMP_PATH

        echo "release local docker image  "
        sudo docker tag $imageVersionName $imageLatestName
    fi;
    return $?;
}

# 生成镜像文件
function executeShell(){
    local JAR_PATH=$1;

    if [ -n "$SHELL_COMMAND" ]; then
        if [ $SSH_FLAG = 1 ];then
            sshCommand "$SHELL_COMMAND"
        else
            localCommand "$SHELL_COMMAND";
        fi;
    fi;

    return $?;
}

# 结束时需要执行的函数
function end(){
   if [ $NOT_CLEAR = 0 ]; then
       removeDockerfile
       removeFile
   fi;
   return $?;
}

# 获取本程序能够支持的参数
function initPara(){

    # ------------------------------脚本本身相关参数-------------------------------------
    # 是否开启日志
    LOG=$(isPara "--log" "$@");
    # 是否开启帮助
    HELP_FLAG=$(isPara "--help" "$@");
    # 不清除临时文件
    NOT_CLEAR=$(isPara "--c" "$@");
    # 帮助的语言版本
    LANGUAGE=$(getDefaultPara "$(getParaFirst "--l" "$@")" "$LANGUAGE");
    # 用当前shell脚本的目录作为基础目录
    SH_PATH=$(isPara "--sh" "$@");

    # 打印变量名称-值
    logGrobleVar LOG HELP_FLAG NOT_CLEAR LANGUAGE SH_PATH

    # ------------------------------临时处理相关参数-------------------------------------
    # ssh服务器上临时路径
    TEMP_PATH=$(getDefaultPara "$(getParaFirst "--t" "$@")" "$TEMP_PATH");

    # 打印变量名称-值
    logGrobleVar TEMP_PATH

    # ------------------------------maven相关参数-------------------------------------
    # 是否开启maven打包
    MAVEN_NOT_FLAG=$(isPara "-mcc" "$@");
    MAVEN_COMMAND=$(getParaFirst "-mc" "$@");

    # 打印变量名称-值
    logGrobleVar MAVEN_NOT_FLAG MAVEN_COMMAND

    # ------------------------------dockerfile相关参数-------------------------------------
    # Docker打包标记
    DOCKER_CLOSE_FLAG=$(isPara "-dcc" "$@");
    # 作者
    AUTHOR=$(getDefaultPara "$(getParaFirst "-da" "$@")" "$AUTHOR");
    # 作者
    EXPOSE=$(getDefaultPara "$(getParaFirst "-dp" "$@")" "$EXPOSE");
    # 打印变量名称-值
    logGrobleVar DOCKER_CLOSE_FLAG AUTHOR EXPOSE

    # ------------------------------ssh相关参数-------------------------------------
    # 是否开启ssh,以及ssh的服务器
    SSH_FLAG=$(isPara "-ssh" "$@");
    SSH_SERVER=$(getParaFirst "-ssh" "$@");
    # ssh端口,默认22
    SSH_PORT=$(getDefaultPara "$(getParaFirst "-ssp" "$@")" "$SSH_PORT");

    # 打印变量名称-值
    logGrobleVar SSH_FLAG SSH_SERVER SSH_PORT

    # ------------------------------java命令相关参数-------------------------------------
    # jar的路径
    JAR_PATH=$(getDefaultPara "$(getParaFirst "-jp" "$@")" "$JAR_PATH");
    # java内存参数
    JAVA_MEMORY=$(getDefaultPara "$(getParaFirst "-jm" "$@")" "$JAVA_MEMORY");
    # java参数
    JAVA_ARGUMENTS=$(getDefaultPara "$(getParaFirst "-ja" "$@")" "$JAVA_ARGUMENTS");

    # 打印变量名称-值
    logGrobleVar JAR_PATH JAVA_MEMORY JAVA_ARGUMENTS

    # ------------------------------docker运行相关参数-------------------------------------
    # 先运行docker image后停止
    # RUN_FRONT=$(isPara "-ds" "$@");

    # Docker执行相关命令
    SHELL_COMMAND=$(getParaFirst "-sh" "$@");
    logGrobleVar SHELL_COMMAND

    # 打印变量名称-值
    # logGrobleVar RUN_FRONT
}

# 显示help信息,当开启 --help时,则停止执行程序
function help(){
    if [ $HELP_FLAG = 0 ];then
        return $?;
    fi;

    language "English help:" "中文帮助:"
    language "The java written by yanzuoguang@qq.com is packaged and published to the docker help document. Syntax format:" "\
yanzuoguang@qq.com编写的java打包并且发布到docker帮助文档,语法格式:"
    language "$SHELL_NAME"

    # ------------------------------脚本本身相关参数-------------------------------------
    language "  [--log] : Turn on the log information display of this shell document, and the global variables and extension information will be displayed for this debugging and editing mode." "\
  [--log] : 开启本shell文档的日志信息显示,会显示全局变量以及扩展信息,用于本调试编辑模式. "

    language "  [--help] : display help information. " "\
  [--help] : 显示帮助信息. "

    language "  [--c] : After execution, temporary files are not deleted. " "\
  [--c] : 执行完成后,不删除临时文件. "

    language "  [--l en|ch ] : Set Shell language,default as ch. En = English, ch = Chinese" "\
  [--l en|ch ] : 设置Shell语言,默认ch.en=英语,ch=中文. "

    language "  [--sh] : Set the current script directory as the execution directory. " "\
  [--sh] : 设置当前脚本目录为执行目录。 "

    # ------------------------------临时处理相关参数-------------------------------------
    language "  [--t temp_folder_path] : Set the temporary directory of shell to cache intermediate files, which will be deleted after execution. " "\
  [--t temp_folder_path] : 设置Shell的临时目录,用于缓存中间文件,在执行完成后会被删除. "

    # ------------------------------maven相关参数-------------------------------------
    language "  [-mcc] : Maven off switch will turn off Maven packaging after setting." "\
  [-mcc] : maven关闭开关,在设置后将会关闭maven打包."

    language "  [-mc maven_command] : Customize the Maven packaging command. The default command is MVN clean package. " "\
  [-mc maven_command] : 自定义maven打包命令,默认命令为: mvn clean package. "

    # ------------------------------dockerfile相关参数-------------------------------------
     language "  [-dcc] : The docker off switch will turn off docker packaging after setting." "\
  [-dcc] : docker关闭开关,在设置后将会关闭docker打包."

     language "  [-da author] : Docker author settings, used to generate dockerfile files." "\
  [-da author] : docker作者设置,用于生成dockerfile文件."

     language "  [-dp expose] : Docker port setting, used to generate dockerfile file." "\
  [-dp expose] : docker端口设置,用于生成dockerfile文件."

    # ------------------------------ssh相关参数-------------------------------------
     language "  [-ssh user@ip]: The server address of the SSH that docker needs to publish to." "\
  [-ssh user@ip]: Docker需要发布到的ssh的服务器地址."

     language "  [-ssp ssh_port] : The server port of the SSH to which docker needs to be published. The default value is '$SSH_PATH'" "\
  [-ssp ssh_port] : Docker需要发布到的ssh的服务器端口,默认为:'$SSH_PATH'"

    # ------------------------------java命令相关参数-------------------------------------

     language "  [-jp jar_path]: The path of the jar package, relative to the start of the script." "\
  [-jp jar_path]: jar包所在的路径,相对于脚本开始."

     language "  [-jm java_memory_arguments] : When docker is packaged, set the JAVA memory parameter information. The default value is'$JAVA_MEMORY'" "\
  [-jm java_memory_arguments] : Docker打包时,设置Java的内存参数相关信息,默认为:'$JAVA_MEMORY'"

     language "  [-ja jar_arguments] : When docker is packing, set the execution related parameters of jar package. The default value is '$JAVA_ARGUMENTS'" "\
  [-ja jar_arguments] : Docker打包时,设置Jar包的执行相关参数,默认为:'$JAVA_ARGUMENTS'"

    # ------------------------------当发布成docker后需要执行的脚本命令-------------------------------------
     language "  [-sh shell] : Shell commands to be executed after docker is published." "\
  [-sh shell] : docker发布后,需要执行的shell命令."

    language "eg:" "例子:"
    language "  $SHELL_NAME --help --l en"
    language "  $SHELL_NAME "
    language "  $SHELL_NAME -mc "mvn clean package deploy""
    language "  $SHELL_NAME -jm "-Xms200m -Xmx3000m" -ja "--spring.profiles.active=prod --yzg.config.url=/home/tbd_pd/conf/tbd_reg.properties""
    language "  $SHELL_NAME -ssh root@l206 -ssp 22"

    language "normal usage:" "通常用法:"
    language "  1.On the docker target server, first create the docker network with the command:" "  1.在docker目标服务器上,先用命令创建docker网络:"
    language "    docker network create --gateway=192.168.100.1 --subnet=192.168.100.0/24 evndm"
    language "  2.Pack the current directory, force to close the docker service, and start a new docker service:" "  2.打包当前目录,强制关闭docker服务,并且启动新的docker服务:"
    language "    $SHELL_NAME -ssh root@l88 -dp "6888" -jm "-Xms200m" -sh "docker rm -f tbd-gateway;docker run -it -d  -p 6888:6888 --net evndm --ip 192.168.100.4 --restart always --name tbd-gateway tbd-gateway:latest""

    exit 0;
}

# 对错误的初始化处理
function initError(){
    # 设置当程序错误,则结束程序
    set +e;

    # 非正常退出时执行的信息
    handle_exit_code() {
        ERROR_CODE="$?";
        if [ "$ERROR_CODE" != "0" ]; then
            printf -- "an error occurred. cleaning up now... ";
            # ... cleanup code ...
            end;

            printf -- "DONE.\nExiting with error code ${ERROR_CODE}.\n";
        fi;
        exit ${ERROR_CODE};
    }

    trap "handle_exit_code" EXIT;
}

# 起始运行函数
function main(){
    initError;

    # 获取当前脚本名称
    SHELL_NAME=$0

    # 初始化shell参数
    initPara "$@";

    # 显示帮助信息,当显示帮助信息时,停止往下执行
    help;

    # 通过 getCurrent 获取当前目录
    if [ $SH_PATH = 1 ];then
        goCurrent;
    fi;

    if [ $MAVEN_NOT_FLAG = 0 ];then
        # 调用maven打包
        mavenPackage
    fi;

    if [ $DOCKER_CLOSE_FLAG = 0 ];then
        # 获取当前目录target下的jar文件
        # 获取jar路径和文件 \
        # findjar $TARGET_PATH
        jarPath=$(findJar $JAR_PATH)

        # 生成dockerfile文件
        releaseDockerfile $jarPath

        # 复制dockerfile和jar包到指定目录
        copyFile $jarPath

        # 生成docker image
        releaseImage $jarPath

        # 执行docker命令
        executeShell $jarPath
    fi;

    # 删除临时文件
    end;
}

# 调用main函数,并且将所有参数传递过去
main "$@"

node_docker.sh

#!/bin/bash

#中文帮助:
#yanzuoguang@qq.com编写的java打包并且发布到docker帮助文档,语法格式:
#./node_docker.sh
#  [--log] : 开启本shell文档的日志信息显示,会显示全局变量以及扩展信息,用于本调试编辑模式.
#  [--help] : 显示帮助信息.
#  [--c] : 执行完成后,不删除临时文件.
#  [--l en|ch ] : 设置Shell语言,默认ch.en=英语,ch=中文.
#  [--sh] : 设置当前脚本目录为执行目录。
#  [--t temp_folder_path] : 设置Shell的临时目录,用于缓存中间文件,在执行完成后会被删除.
#  [-n app_name] : 设置程序名称,默认为:node_test.
#  [-p app_path] : 设置程序在npm run build之后的打包路径,默认为:./app/.
#  [-ncc] : node关闭开关,在设置后将会关闭node打包.
#  [-nc node_command] : 自定义node打包命令,默认命令为: mvn clean package.
#  [-dcc] : docker关闭开关,在设置后将会关闭docker打包.
#  [-da author] : docker作者设置,用于生成dockerfile文件.
#  [-dp expose] : docker端口设置,用于生成dockerfile文件.
#  [-ssh user@ip]: Docker需要发布到的ssh的服务器地址.
#  [-ssp ssh_port] : Docker需要发布到的ssh的服务器端口,默认为:''
#  [-sh shell] : docker发布后,需要执行的shell命令.
#例子:
#  ./node_docker.sh --help --l en
#  ./node_docker.sh -n "app_name"
#  ./node_docker.sh -n "app_name" -nc "npm run build"
#  ./node_docker.sh -n "app_name" -ssh root@l206 -ssp 22
#通常用法:
#  1.在docker目标服务器上,先用命令创建docker网络:
#    docker network create --gateway=192.168.100.1 --subnet=192.168.100.0/24 evndm
#  2.打包当前目录,强制关闭docker服务,并且启动新的docker服务:
#    ./node_docker.sh -n "app_name" -ssh root@l206 -sh "sudo docker rm -f app_name;sudo docker run -it -d --net evndm102 --ip 192.168.102.2 --restart always --name app_name app_name:latest"

#English help:
#The java written by yanzuoguang@qq.com is packaged and published to the docker help document. Syntax format:
#./node_docker.sh
#  [--log] : Turn on the log information display of this shell document, and the global variables and extension information will be displayed for this debugging and editing mode.
#  [--help] : display help information.
#  [--c] : After execution, temporary files are not deleted.
#  [--l en|ch ] : Set Shell language,default as ch. En = English, ch = Chinese
#  [--sh] : Set the current script directory as the execution directory.
#  [--t temp_folder_path] : Set the temporary directory of shell to cache intermediate files, which will be deleted after execution.
#  [-n app_name] : Set the program name. The default is:node_test.
#  [-p app_path] : Set the packing path of the program after npm run build. The default is:./app/.
#  [-ncc] : node off switch will turn off node packaging after setting.
#  [-nc node_command] : Customize the node packaging command. The default command is MVN clean package.
#  [-dcc] : The docker off switch will turn off docker packaging after setting.
#  [-da author] : Docker author settings, used to generate dockerfile files.
#  [-dp expose] : Docker port setting, used to generate dockerfile file.
#  [-ssh user@ip]: The server address of the SSH that docker needs to publish to.
#  [-ssp ssh_port] : The server port of the SSH to which docker needs to be published. The default value is ''
#  [-sh shell] : Shell commands to be executed after docker is published.
#eg:
#  ./node_docker.sh --help --l en
#  ./node_docker.sh -n "app_name"
#  ./node_docker.sh -n "app_name" -nc "npm run build"
#  ./node_docker.sh -n "app_name" -ssh root@l206 -ssp 22
#normal usage:
#  1.On the docker target server, first create the docker network with the command:
#    docker network create --gateway=192.168.100.1 --subnet=192.168.100.0/24 evndm
#  2.Pack the current directory, force to close the docker service, and start a new docker service:
#    ./node_docker.sh -n "app_name" -ssh root@l206 -sh "sudo docker rm -f app_name;sudo docker run -it -d --net evndm102 --ip 192.168.102.2 --restart always --name app_name app_name:latest"

function getTimeName(){
    local current=`date "+%Y%m%d%H%M%S"`
    echo $current;
    return $?;
}

# 显示当期时间搓
function getTime(){
    local current=`date "+%Y-%m-%d %H:%M:%S"`
    local timeStamp=`date -d "$current" +%s`
    #将current转换为时间戳,精确到毫秒,下面这个10#代表10进制来实现
    local currentTimeStamp=$((timeStamp*1000+10#`date "+%N"`/1000000))
    echo $currentTimeStamp;
    return $?;
}

# ------------------------------脚本本身相关参数-------------------------------------
# 是否开启日志
LOG=0
# 是否开启help标记,具体帮助信息请参数help信息
HELP_FLAG=0;
# 不清徐临时文件
NOT_CLEAR=0;
# 语言版本
LANGUAGE="ch";
# 用当前shell脚本的目录作为基础目录
SH_PATH=0

# ------------------------------node相关参数---------------------------------------
# APP名称
APP_NAME="node_test";
APP_PATH="./app/";
# 是否开启node打包
NODE_NOT_FLAG=0;
NODE_COMMAND='';

# ------------------------------ssh相关参数-----------------------------------------
# 是否开启ssh,以及ssh的服务器
SSH_FLAG=0;
SSH_SERVER="";
# ssh端口,默认22
SSH_PORT="22";

# ------------------------------dockerfile相关参数-------------------------------------
# Docker打包标记
DOCKER_CLOSE_FLAG=0;
# 作者
AUTHOR="yanzuoguang yanzuoguang@qq.com";
# 暴露的端口
EXPOSE="20 80";

# ------------------------------docker运行相关参数-------------------------------------
# 先运行docker image后停止, 先启动后停止=1, 先停止后运行=0
# RUN_FRONT=0;

# 需要执行的命令
SHELL_COMMAND="";

# ------------------------------临时处理相关参数,shell内部变量--------------------------
# 服务器上临时路径,假如是远程,则是远程目录的临时路径
TEMP_PATH="/tmp/yanzuoguang/$(getTime)/";
# 当前脚本名称
SHELL_NAME='';
# dockerfile临时文件名
TEMP_DOCKERFILE='Dockerfile.tmp';

function language(){
    if [ $LANGUAGE = "ch" -a -n "$2" ];then
        # eval "print -- '$2'"
        echo "$2"
    else
        # eval "print -- '$1'"
        echo "$1"
    fi;
    return $?;
}

## 获取当前目录函数
function getCurrent(){
    # 获取当前脚本目录
    local currDir="$(dirname $0);"
    # 去掉最后的符号,并且显示出来
    echo ${currDir%?};
    # 返回当前函数的最后一条命令的执行状态
    return $?;
}

## 进入当前脚本目录
function goCurrent(){
    local nowPath=$(getCurrent);
    # 进入当前目录
    goPath $nowPath;
}

## 获取当前命令运行目录
function getCurrentCommand(){
    # 当前脚本目录
    pwd;
    # 返回当前函数的最后一条命令的执行状态
    return $?;
}

## 打印全局变量的值
function logGrobleVar(){
    if [ $LOG = 1 ];then
        for i in "$@"; do
            printf -- "$i:";
            eval 'printf -- "$'$i'\t"';
        done
        printf -- "\n";
    fi;
    return $?;
}

# 用于判断是否存在参数名称,调用方法为: getPara "-t" "$@" , 存在则会返回1,不存在返回0
# isPara "-a" "$@";
# isPara "-b" "$@";
function isPara(){
    local find=0;
    for i in "$@"; do
        #判断字符串是否相等,相等则变量+1
        if [ "$i" = "$1" ];then
        ((find=find+1))
        # echo $find;
        fi
        # 获取非第一个变量的值
        if [ $find = 2 ];then
        # 返回1表示包含该参数
        echo 1;
        return $?;
        fi
    done
    # 返回0表示不包含该参数
    echo 0
    return $?;
}

# 日志打印函数,在开启日志模式时生效
function log(){
    if [ $LOG = 1 ];then
        # 显示找到参数的下一个参数值
        language "$@";
    fi
}

# 用于获取当前参数的值,调用方法为: getPara "-t" "$@" , 存在则返回值,否则返回空
# a=$(getPara "-a" "$@");
# b=$(getPara "-b" "$@");
function getPara(){
    local find=0;
    for i in "$@"; do
        # 获取非第一个变量的值,等于1时表示需要找到的变量,等于2表示找到该变量的值
        if [ $find = 2 ];then
            # 显示找到参数的下一个参数值
            if [[ $i == -* ]];
            then
                break;
            else
                echo $i;
            fi;
        fi
        #判断字符串是否相等,相等则变量+1
        if [ "$i" = "$1" ];then
            # 找到次数+1
            ((find=find+1))
            # echo $find;
        fi
    done
    return $?;
}
# 用于获取当前参数的值,调用方法为: getPara "-t" "$@" , 存在则返回值,否则返回空
# a=$(getPara "-a" "$@");
# b=$(getPara "-b" "$@");
function getParaFirst(){
    local find=0;
    for i in "$@"; do
        # 获取非第一个变量的值,等于1时表示需要找到的变量,等于2表示找到该变量的值
        if [ $find = 2 ];then
            echo $i;
            break;
        fi
        #判断字符串是否相等,相等则变量+1
        if [ "$i" = "$1" ];then
            # 找到次数+1
            ((find=find+1))
            # echo $find;
        fi
    done
    return $?;
}

# 获取第一个不为空的参数
function getDefaultPara(){
    for i in "$@"; do
    if [ -z "$i" ]; then
        # echo "STRING is empty"
        continue;
    else
        echo $i;
        break;
        # echo "STRING is not empty"
    fi
    done
    return $?;
}

# 执行本地命令
function localCommand(){
    # 获取需要执行的命令行
    local COMMAND=$1;
    # 将命令行的分割符替换成换行符
    local COMMAND_LINE=$(echo "$COMMAND"|tr ";" "\n");
    # 输出命令行到循环读取
    echo "$COMMAND_LINE"|while read -r i; do
        echo "\$ $i";
        ${i};
    done

    return $?;
}

# 执行ssh命令
function sshCommand(){
    local COMMAND=$1;

    # 检测ssh命令是否存在
    _=$(command -v ssh);
    if [ "$?" != "0" ]; then
        printf -- 'You don'\''t seem to have ssh installed.\n';
        printf -- 'Get it: yum -y install ssh \n';
        printf -- 'Exiting with code 127...\n';
        exit 127;
    fi;

    echo ssh -p $SSH_PORT $SSH_SERVER "$COMMAND;exit";
    ssh -p $SSH_PORT $SSH_SERVER "$COMMAND;exit";
    return $?;
}

# sshCopy
function sshCopy(){
    local LOCAL_PATH=$1;
    local SERVER_PATH=$2;
    local ARGS=$3;

    # 检测ssh命令是否存在
    _=$(command -v scp);
    if [ "$?" != "0" ]; then
        printf -- 'You don'\''t seem to have ssh installed.\n';
        printf -- 'Get it: yum -y install ssh \n';
        printf -- 'Exiting with code 127...\n';
        exit 127;
    fi;

    echo scp $ARGS $LOCAL_PATH $SSH_SERVER:$SERVER_PATH;
    scp $ARGS $LOCAL_PATH $SSH_SERVER:$SERVER_PATH;
    return $?;
}

# 显示当前目录
function displayPath(){
    log "now path:$(pwd)" "当前路径:$(pwd)";
}

# 进入到指定目录
function goPath(){
    log "Access path: $1" "进入路径:$1";
    # 进入到指定目录
    cd $1;
    # 显示当前路径
    displayPath;
    return $?;
}

# 获取文件名
function getFileName(){
    echo ${1##*/};
    return $?;
}

# 获取不带后缀的文件名
function getFileNameNotExt(){
    local tmp=${1##*/};
    echo ${tmp%.*};
    return $?;
}

# 检测node命令是否安装
function checkNodeCommand(){
    _=$(command -v npm);
    if [ "$?" != "0" ]; then
        printf -- 'You don'\''t seem to have node installed.\n';
        printf -- 'Get it: https://www.docker.com/community-edition\n';
        printf -- 'Exiting with code 127...\n';
        exit 127;
    fi;
}

# node 打包成jar包
function nodePackage(){
    language "In Node packaging, the command is:" "node打包中,命令为:" ;
    # 判断是否自定义node命令
    if [ -n "$NODE_COMMAND" ]; then
        localCommand "$NODE_COMMAND";
    else
        checkNodeCommand;
        echo npm run build;
        npm run build;
    fi;
}
# 找到jar文件,相对当前目录
function findJar(){
    for name in `find $1 -name *.jar`
    do
    echo $name
    done
    return $?;
}

# 在临时目录中编写dockerfile文件
function releaseDockerfile(){

    # 生成临时dockerfile文件
    echo 'release dockerfile temp...';

    echo 'FROM nginx:1.15.0' > $TEMP_DOCKERFILE
    echo 'MAINTAINER '$AUTHOR >> $TEMP_DOCKERFILE
    echo 'ADD "./app/" "/usr/share/nginx/html/"' >> $TEMP_DOCKERFILE
    if [ -z "$EXPOSE" ]; then
        echo 'EXPOSE '$EXPOSE >> $TEMP_DOCKERFILE
    fi;

    return $?;
}

# 删除临时目录中的dockerfile文件
function removeDockerfile(){
    # 删除临时dockerfile
    echo 'remove temp dockerfile';
    rm -rf $TEMP_DOCKERFILE
}

# 复制jar包到临时目录中
function copyFile(){
    local FROM_PATH="$APP_PATH";
    local TO_PATH="$TEMP_PATH/app/";
    local TO_DOCKERFILE=$TEMP_PATH$(getFileNameNotExt $TEMP_DOCKERFILE);
    removeFile;

    if [ $SSH_FLAG = 1 ];then
        echo "mkdir temp path $TEMP_PATH";
        sshCommand "mkdir -p $TEMP_PATH"

        # 将本地文件复制到远程目录
        echo "copy $FROM_PATH to temp path $SSH_SERVER:$TO_PATH."
        sshCopy "$FROM_PATH" "$TO_PATH" "-r"

        echo "copy $TEMP_DOCKERFILE to temp path $SSH_SERVER:$TO_DOCKERFILE.";
        sshCopy "$TEMP_DOCKERFILE" "$TO_DOCKERFILE"
    else
        echo "mkdir temp path $TEMP_PATH";
        mkdir -p $TEMP_PATH

        echo cp -r "$FROM_PATH" "$TO_PATH"
        cp -r "$FROM_PATH" "$TO_PATH"

        echo cp "$TEMP_DOCKERFILE" "$TO_DOCKERFILE"
        cp "$TEMP_DOCKERFILE" "$TO_DOCKERFILE"
    fi;

    return $?;
}

# 删除复制到的目录中的文件
function removeFile(){
    if [ $SSH_FLAG = 1 ];then
        echo "remove ssh $SSH_SERVER:$TEMP_PATH to temp path..."
        sshCommand "rm -rf '$TEMP_PATH'";
    else
        echo "remove local $TEMP_PATH temp path..."
        rm -rf "$TEMP_PATH";
    fi;
    return $?;
}

# 检测docker命令是否安装
function checkDockerCommand(){
    _=$(command -v docker);
    if [ "$?" != "0" ]; then
      printf -- 'You don'\''t seem to have Docker installed.\n';
      printf -- 'Get it: https://www.docker.com/community-edition\n';
      printf -- 'Exiting with code 127...\n';
      exit 127;
    fi;
}

# 生成镜像文件
function releaseImage(){
    local dockerName="$APP_NAME";
    local timeName="$(getTimeName)";
    local imageVersionName="$dockerName:v$timeName";
    local imageLatestName="$dockerName:latest";
    echo "release ssh docker image $imageVersionName and $imageLatestName"

    if [ $SSH_FLAG = 1 ];then
        sshCommand "sudo docker build -t $imageVersionName $TEMP_PATH;sudo docker tag $imageVersionName $imageLatestName"
    else
        checkDockerCommand;

        localCommand "sudo docker build -t $imageVersionName $TEMP_PATH;sudo docker tag $imageVersionName $imageLatestName"
    fi;
    return $?;
}

# 生成镜像文件
function executeShell(){
    local JAR_PATH=$1;

    if [ -n "$SHELL_COMMAND" ]; then
        if [ $SSH_FLAG = 1 ];then
            sshCommand "$SHELL_COMMAND"
        else
            localCommand "$SHELL_COMMAND";
        fi;
    fi;

    return $?;
}

# 结束时需要执行的函数
function end(){
   if [ $NOT_CLEAR = 0 ]; then
       removeDockerfile
       removeFile
   fi;
   return $?;
}

# 获取本程序能够支持的参数
function initPara(){

    # ------------------------------脚本本身相关参数-------------------------------------
    # 是否开启日志
    LOG=$(isPara "--log" "$@");
    # 是否开启帮助
    HELP_FLAG=$(isPara "--help" "$@");
    # 不清除临时文件
    NOT_CLEAR=$(isPara "--c" "$@");
    # 帮助的语言版本
    LANGUAGE=$(getDefaultPara "$(getParaFirst "--l" "$@")" "$LANGUAGE");
    # 用当前shell脚本的目录作为基础目录
    SH_PATH=$(isPara "--sh" "$@");

    # 打印变量名称-值
    logGrobleVar LOG HELP_FLAG NOT_CLEAR LANGUAGE SH_PATH

    # ------------------------------临时处理相关参数-------------------------------------
    # ssh服务器上临时路径
    TEMP_PATH=$(getDefaultPara "$(getParaFirst "--t" "$@")" "$TEMP_PATH");

    # 打印变量名称-值
    logGrobleVar TEMP_PATH

    # ------------------------------node相关参数-------------------------------------
    # APP名称,以及参数
    APP_NAME=$(getDefaultPara "$(getParaFirst "-n" "$@")" "$APP_NAME");
    APP_PATH=$(getDefaultPara "$(getParaFirst "-p" "$@")" "$APP_PATH");
    # 是否开启node打包
    NODE_NOT_FLAG=$(isPara "-ncc" "$@");
    NODE_COMMAND=$(getParaFirst "-nc" "$@");

    # 打印变量名称-值
    logGrobleVar APP_NAME APP_PATH NODE_NOT_FLAG NODE_COMMAND

    # ------------------------------dockerfile相关参数-------------------------------------
    # Docker打包标记
    DOCKER_CLOSE_FLAG=$(isPara "-dcc" "$@");
    # 作者
    AUTHOR=$(getDefaultPara "$(getParaFirst "-da" "$@")" "$AUTHOR");
    # 作者
    EXPOSE=$(getDefaultPara "$(getParaFirst "-dp" "$@")" "$EXPOSE");
    # 打印变量名称-值
    logGrobleVar DOCKER_CLOSE_FLAG AUTHOR EXPOSE

    # ------------------------------ssh相关参数-------------------------------------
    # 是否开启ssh,以及ssh的服务器
    SSH_FLAG=$(isPara "-ssh" "$@");
    SSH_SERVER=$(getParaFirst "-ssh" "$@");
    # ssh端口,默认22
    SSH_PORT=$(getDefaultPara "$(getParaFirst "-ssp" "$@")" "$SSH_PORT");

    # 打印变量名称-值
    logGrobleVar SSH_FLAG SSH_SERVER SSH_PORT

    # ------------------------------docker运行相关参数-------------------------------------
    # 先运行docker image后停止
    # RUN_FRONT=$(isPara "-ds" "$@");

    # Docker执行相关命令
    SHELL_COMMAND=$(getParaFirst "-sh" "$@");
    logGrobleVar SHELL_COMMAND

    # 打印变量名称-值
    # logGrobleVar RUN_FRONT
}

# 显示help信息,当开启 --help时,则停止执行程序
function help(){
    if [ $HELP_FLAG = 0 ];then
        return $?;
    fi;

    language "English help:" "中文帮助:"
    language "The java written by yanzuoguang@qq.com is packaged and published to the docker help document. Syntax format:" "\
yanzuoguang@qq.com编写的java打包并且发布到docker帮助文档,语法格式:"
    language "$SHELL_NAME"

    # ------------------------------脚本本身相关参数-------------------------------------
    language "  [--log] : Turn on the log information display of this shell document, and the global variables and extension information will be displayed for this debugging and editing mode." "\
  [--log] : 开启本shell文档的日志信息显示,会显示全局变量以及扩展信息,用于本调试编辑模式. "

    language "  [--help] : display help information. " "\
  [--help] : 显示帮助信息. "

    language "  [--c] : After execution, temporary files are not deleted. " "\
  [--c] : 执行完成后,不删除临时文件. "

    language "  [--l en|ch ] : Set Shell language,default as ch. En = English, ch = Chinese" "\
  [--l en|ch ] : 设置Shell语言,默认ch.en=英语,ch=中文. "

    language "  [--sh] : Set the current script directory as the execution directory. " "\
  [--sh] : 设置当前脚本目录为执行目录。 "

    # ------------------------------临时处理相关参数-------------------------------------
    language "  [--t temp_folder_path] : Set the temporary directory of shell to cache intermediate files, which will be deleted after execution. " "\
  [--t temp_folder_path] : 设置Shell的临时目录,用于缓存中间文件,在执行完成后会被删除. "

    # ------------------------------node相关参数-------------------------------------
    language "  [-n app_name] : Set the program name. The default is:$APP_NAME." "\
  [-n app_name] : 设置程序名称,默认为:$APP_NAME."

    language "  [-p app_path] : Set the packing path of the program after npm run build. The default is:$APP_PATH." "\
  [-p app_path] : 设置程序在npm run build之后的打包路径,默认为:$APP_PATH."

    language "  [-ncc] : node off switch will turn off node packaging after setting." "\
  [-ncc] : node关闭开关,在设置后将会关闭node打包."

    language "  [-nc node_command] : Customize the node packaging command. The default command is MVN clean package. " "\
  [-nc node_command] : 自定义node打包命令,默认命令为: mvn clean package. "

    # ------------------------------dockerfile相关参数-------------------------------------
     language "  [-dcc] : The docker off switch will turn off docker packaging after setting." "\
  [-dcc] : docker关闭开关,在设置后将会关闭docker打包."

     language "  [-da author] : Docker author settings, used to generate dockerfile files." "\
  [-da author] : docker作者设置,用于生成dockerfile文件."

     language "  [-dp expose] : Docker port setting, used to generate dockerfile file." "\
  [-dp expose] : docker端口设置,用于生成dockerfile文件."

    # ------------------------------ssh相关参数-------------------------------------
     language "  [-ssh user@ip]: The server address of the SSH that docker needs to publish to." "\
  [-ssh user@ip]: Docker需要发布到的ssh的服务器地址."

     language "  [-ssp ssh_port] : The server port of the SSH to which docker needs to be published. The default value is '$SSH_PATH'" "\
  [-ssp ssh_port] : Docker需要发布到的ssh的服务器端口,默认为:'$SSH_PATH'"

    # ------------------------------当发布成docker后需要执行的脚本命令-------------------------------------
     language "  [-sh shell] : Shell commands to be executed after docker is published." "\
  [-sh shell] : docker发布后,需要执行的shell命令."

    language "eg:" "例子:"
    language "  $SHELL_NAME --help --l en"
    language "  $SHELL_NAME -n "app_name""
    language "  $SHELL_NAME -n "app_name" -nc "npm run build""
    language "  $SHELL_NAME -n "app_name" -ssh root@l206 -ssp 22"

    language "normal usage:" "通常用法:"
    language "  1.On the docker target server, first create the docker network with the command:" "  1.在docker目标服务器上,先用命令创建docker网络:"
    language "    docker network create --gateway=192.168.100.1 --subnet=192.168.100.0/24 evndm"
    language "  2.Pack the current directory, force to close the docker service, and start a new docker service:" "  2.打包当前目录,强制关闭docker服务,并且启动新的docker服务:"
    language "    $SHELL_NAME -n "app_name" -ssh root@l206 -sh "sudo docker rm -f app_name;sudo docker run -it -d --net evndm102 --ip 192.168.102.2 --restart always --name app_name app_name:latest""

    exit 0;
}

# 对错误的初始化处理
function initError(){
    # 设置当程序错误,则结束程序
    set +e;

    # 非正常退出时执行的信息
    handle_exit_code() {
        ERROR_CODE="$?";
        if [ "$ERROR_CODE" != "0" ]; then
            printf -- "an error occurred. cleaning up now... ";
            # ... cleanup code ...
            end;

            printf -- "DONE.\nExiting with error code ${ERROR_CODE}.\n";
        fi;
        exit ${ERROR_CODE};
    }

    trap "handle_exit_code" EXIT;
}

# 起始运行函数
function main(){
    initError;

    # 获取当前脚本名称
    SHELL_NAME=$0

    # 初始化shell参数
    initPara "$@";

    # 显示帮助信息,当显示帮助信息时,停止往下执行
    help;

    # 通过 getCurrent 获取当前目录
    if [ $SH_PATH = 1 ];then
        goCurrent;
    fi;

    if [ $NODE_NOT_FLAG = 0 ];then
        # 调用node打包
        nodePackage
    fi;

    if [ $DOCKER_CLOSE_FLAG = 0 ];then
        # 生成dockerfile文件
        releaseDockerfile

        # 复制dockerfile和build之后的结果到指定目录
        copyFile

        # 生成docker image
        releaseImage

        # 执行docker命令
        executeShell
    fi;

    # 删除临时文件
    end;
}

# 调用main函数,并且将所有参数传递过去
main "$@"