前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >nifi.sh 脚本解读

nifi.sh 脚本解读

作者头像
@阿诚
发布2020-09-01 15:19:28
发布2020-09-01 15:19:28
1.4K00
代码可运行
举报
文章被收录于专栏:Panda诚Panda诚
运行总次数:0
代码可运行

内容:

整个脚本分为三部分,第一部分是确定NIFI各个路径 目录的确定,设置环境变量,第二部分是方法区。第三部分是脚本逻辑代码的入口,粗略的根据不同的参数去执行不同的方法。以下脚本有详细注释:

代码语言:javascript
代码运行次数:0
复制
#!/bin/sh

# ==========================
# 1、查找文件的路径 start
# ==========================

# 由于MacOS X、FreeBSD和其他一些系统缺少gnu readlink,我们使用了基于以下StackOverflow注释http://stackoverflow.com/a/1116890/888876的更可移植的方法

## 特殊变量 当前脚本的文件名
TARGET_FILE=$0
#跳转到当前脚本所在的目录
cd $(dirname $TARGET_FILE)
## TARGET_FILE=nifi.sh
TARGET_FILE=$(basename $TARGET_FILE)

## 遍历(可能的)符号链接链   -L filename,判断文件是否是链接文件
while [ -L "$TARGET_FILE" ]
do
    TARGET_FILE=$(readlink $TARGET_FILE)
    cd $(dirname $TARGET_FILE)
    TARGET_FILE=$(basename $TARGET_FILE)
done


# pwd -P  显示出实际路径,而非使用连接(link)路径。
PHYS_DIR=$(pwd -P)
# 脚本所在目录
SCRIPT_DIR=$PHYS_DIR
PROGNAME=$(basename "$0")
# ==========================
# 查找文件的路径 end
# ==========================

# 执行nifi-env.sh  设置了NIFI的目录环境变量
. "${SCRIPT_DIR}/nifi-env.sh"

# ==========================
#/2、方法区 start
# ==========================

warn() {
    echo "${PROGNAME}: $*"
}

die() {
    warn "$*"
    exit 1
}

# 检测特殊的操作系统,然后做一些特殊操作
detectOS() {
    # Cygwin是一个在windows平台上运行的类UNIX模拟环境
    cygwin=false;
    # AIX,是IBM专有的UNIX操作系统
    aix=false;
    # AS400是IBM早期推出的商用小型机
    os400=false;
    # Darwin是由苹果电脑于2000年所释出的一个开放原始码操作系统
    darwin=false;
    case "$(uname)" in
        CYGWIN*)
            cygwin=true
            ;;
        AIX*)
            aix=true
            ;;
        OS400*)
            os400=true
            ;;
        Darwin)
            darwin=true
            ;;
    esac
    # For AIX, set an environment variable
    if ${aix}; then
         export LDR_CNTRL=MAXDATA=0xB0000000@DSA
         echo ${LDR_CNTRL}
    fi
    # In addition to those, go around the linux space and query the widely
    # adopted /etc/os-release to detect linux variants
    if [ -f /etc/os-release ]; then
        . /etc/os-release
    fi
}

unlimitFD() {
    # Use the maximum available, or set MAX_FD != -1 to use that
    # 判断 ${MAX_FD}有没有被赋值 条件成立则没有赋值
    if [ "x${MAX_FD}" = "x" ]; then
        MAX_FD="maximum"
    fi

    # 如果可能的话,提升文件描述符的最大数量
    if [ "${os400}" = "false" ] && [ "${cygwin}" = "false" ]; then
        MAX_FD_LIMIT=$(ulimit -H -n)
        if [ "${MAX_FD_LIMIT}" != 'unlimited' ]; then
            if [ $? -eq 0 ]; then
                if [ "${MAX_FD}" = "maximum" -o "${MAX_FD}" = "max" ]; then
                    # use the system max
                    MAX_FD="${MAX_FD_LIMIT}"
                fi

                ulimit -n ${MAX_FD} > /dev/null
                # echo "ulimit -n" `ulimit -n`
                if [ $? -ne 0 ]; then
                    warn "Could not set maximum file descriptor limit: ${MAX_FD}"
                fi
            else
                warn "Could not query system maximum file descriptor limit: ${MAX_FD_LIMIT}"
            fi
        fi
    fi
}


# 找到要执行的JVM
locateJava() {
    # 设置Java虚拟机
    if $cygwin ; then
        [ -n "${JAVA}" ] && JAVA=$(cygpath --unix "${JAVA}")
        [ -n "${JAVA_HOME}" ] && JAVA_HOME=$(cygpath --unix "${JAVA_HOME}")
    fi

    if [ "x${JAVA}" = "x" ] && [ -r /etc/gentoo-release ] ; then
        JAVA_HOME=$(java-config --jre-home)
    fi
    if [ "x${JAVA}" = "x" ]; then
        if [ "x${JAVA_HOME}" != "x" ]; then
            if [ ! -d "${JAVA_HOME}" ]; then
                die "JAVA_HOME is not valid: ${JAVA_HOME}"
            fi
            JAVA="${JAVA_HOME}/bin/java"
        else
            warn "JAVA_HOME not set; results may vary"
            JAVA=$(type java)
            JAVA=$(expr "${JAVA}" : '.* \(/.*\)$')
            if [ "x${JAVA}" = "x" ]; then
                die "java command not found"
            fi
        fi
    fi
    # 如果命令是 env, tools.jar classes.jar也加到 classpath
    if [ "$1" = "env" ]; then
        [ "x${TOOLS_JAR}" =  "x" ] && [ -n "${JAVA_HOME}" ] && TOOLS_JAR=$(find -H "${JAVA_HOME}" -name "tools.jar")
        [ "x${TOOLS_JAR}" =  "x" ] && [ -n "${JAVA_HOME}" ] && TOOLS_JAR=$(find -H "${JAVA_HOME}" -name "classes.jar")
        if [ "x${TOOLS_JAR}" =  "x" ]; then
             warn "Could not locate tools.jar or classes.jar. Please set manually to avail all command features."
        fi
    fi

}
# 初始化
init() {
    # 确定是否需要执行特殊的操作系统处理
    detectOS

    # 如果可能的话,不限制文件描述符的数量
    unlimitFD

    # 找到要执行的JVM
    locateJava "$1"
}

# 将nifi安装为service
install() {
    detectOS

    if [ "${darwin}" = "true"  ] || [ "${cygwin}" = "true" ]; then
        echo 'Installing Apache NiFi as a service is not supported on OS X or Cygwin.'
        exit 1
    fi

    SVC_NAME=nifi
    if [ "x$2" != "x" ] ; then
        SVC_NAME=$2
    fi

    # since systemd seems to honour /etc/init.d we don't still create native systemd services
    # yet...
    initd_dir='/etc/init.d'
    SVC_FILE="${initd_dir}/${SVC_NAME}"

    if [ ! -w  "${initd_dir}" ]; then
        echo "Current user does not have write permissions to ${initd_dir}. Cannot install NiFi as a service."
        exit 1
    fi

# Create the init script, overwriting anything currently present
cat <<SERVICEDESCRIPTOR > ${SVC_FILE}
#!/bin/sh

#
#    Licensed to the Apache Software Foundation (ASF) under one or more
#    contributor license agreements.  See the NOTICE file distributed with
#    this work for additional information regarding copyright ownership.
#    The ASF licenses this file to You under the Apache License, Version 2.0
#    (the "License"); you may not use this file except in compliance with
#    the License.  You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.
#
# chkconfig: 2345 20 80
# description: Apache NiFi is a dataflow system based on the principles of Flow-Based Programming.
#

# Make use of the configured NIFI_HOME directory and pass service requests to the nifi.sh executable
NIFI_HOME=${NIFI_HOME}
bin_dir=\${NIFI_HOME}/bin
nifi_executable=\${bin_dir}/nifi.sh

\${nifi_executable} "\$@"
SERVICEDESCRIPTOR

    if [ ! -f "${SVC_FILE}" ]; then
        echo "Could not create service file ${SVC_FILE}"
        exit 1
    fi

    # Provide the user execute access on the file
    chmod u+x ${SVC_FILE}


    # If SLES or OpenSuse...
    if [ "${ID}" = "opensuse" ] || [ "${ID}" = "sles" ]; then
        rm -f "/etc/rc.d/rc2.d/S65${SVC_NAME}"
        ln -s "/etc/init.d/${SVC_NAME}" "/etc/rc.d/rc2.d/S65${SVC_NAME}" || { echo "Could not create link /etc/rc.d/rc2.d/S65${SVC_NAME}"; exit 1; }
        rm -f "/etc/rc.d/rc2.d/K65${SVC_NAME}"
        ln -s "/etc/init.d/${SVC_NAME}" "/etc/rc.d/rc2.d/K65${SVC_NAME}" || { echo "Could not create link /etc/rc.d/rc2.d/K65${SVC_NAME}"; exit 1; }
        echo "Service ${SVC_NAME} installed"
    # Anything other fallback to the old approach
    else
        rm -f "/etc/rc2.d/S65${SVC_NAME}"
        ln -s "/etc/init.d/${SVC_NAME}" "/etc/rc2.d/S65${SVC_NAME}" || { echo "Could not create link /etc/rc2.d/S65${SVC_NAME}"; exit 1; }
        rm -f "/etc/rc2.d/K65${SVC_NAME}"
        ln -s "/etc/init.d/${SVC_NAME}" "/etc/rc2.d/K65${SVC_NAME}" || { echo "Could not create link /etc/rc2.d/K65${SVC_NAME}"; exit 1; }
        echo "Service ${SVC_NAME} installed"
    fi
}

run() {
    BOOTSTRAP_CONF_DIR="${NIFI_HOME}/conf"
    BOOTSTRAP_CONF="${BOOTSTRAP_CONF_DIR}/bootstrap.conf";
    BOOTSTRAP_LIBS="${NIFI_HOME}/lib/bootstrap/*"

    # 运行NiFi时使用的用户名。此值将在Windows上被忽略。在bootstrap.conf中 run.as= 配置
    run_as_user=$(grep '^\s*run.as' "${BOOTSTRAP_CONF}" | cut -d'=' -f2)
    # 如果以用户身份运行与启动流程相同,则忽略此配置
    if [ "${run_as_user}" = "$(whoami)" ]; then
        unset run_as_user
    fi

    if $cygwin; then
        if [ -n "${run_as_user}" ]; then
            echo "The run.as option is not supported in a Cygwin environment. Exiting."
            exit 1
        fi;

        NIFI_HOME=$(cygpath --path --windows "${NIFI_HOME}")
        NIFI_LOG_DIR=$(cygpath --path --windows "${NIFI_LOG_DIR}")
        NIFI_PID_DIR=$(cygpath --path --windows "${NIFI_PID_DIR}")
        BOOTSTRAP_CONF=$(cygpath --path --windows "${BOOTSTRAP_CONF}")
        BOOTSTRAP_CONF_DIR=$(cygpath --path --windows "${BOOTSTRAP_CONF_DIR}")
        BOOTSTRAP_LIBS=$(cygpath --path --windows "${BOOTSTRAP_LIBS}")
        BOOTSTRAP_CLASSPATH="${BOOTSTRAP_CONF_DIR};${BOOTSTRAP_LIBS}"
        if [ -n "${TOOLS_JAR}" ]; then
            TOOLS_JAR=$(cygpath --path --windows "${TOOLS_JAR}")
            BOOTSTRAP_CLASSPATH="${TOOLS_JAR};${BOOTSTRAP_CLASSPATH}"
        fi
    else
        if [ -n "${run_as_user}" ]; then
            if ! id -u "${run_as_user}" >/dev/null 2>&1; then
                echo "The specified run.as user ${run_as_user} does not exist. Exiting."
                exit 1
            fi
        fi;
        BOOTSTRAP_CLASSPATH="${BOOTSTRAP_CONF_DIR}:${BOOTSTRAP_LIBS}"
        if [ -n "${TOOLS_JAR}" ]; then
            BOOTSTRAP_CLASSPATH="${TOOLS_JAR}:${BOOTSTRAP_CLASSPATH}"
        fi
    fi

    echo
    echo "Java home: ${JAVA_HOME}"
    echo "NiFi home: ${NIFI_HOME}"
    echo
    echo "Bootstrap Config File: ${BOOTSTRAP_CONF}"
    echo

    #在后台运行'start',因为进程将继续运行,监视NiFi。所有其他命令都将很快终止,所以要等待它们

    #设置目录的参数
    # java程序启动参数 -D 在System类中通过getProperties()得到的一串系统属性
    BOOTSTRAP_LOG_PARAMS="-Dorg.apache.nifi.bootstrap.config.log.dir='${NIFI_LOG_DIR}'"
    BOOTSTRAP_PID_PARAMS="-Dorg.apache.nifi.bootstrap.config.pid.dir='${NIFI_PID_DIR}'"
    BOOTSTRAP_CONF_PARAMS="-Dorg.apache.nifi.bootstrap.config.file='${BOOTSTRAP_CONF}'"

    # 去掉一下注釋就允许调试NIFI进程 (或者在bootstrap.conf中取消注释)
    #BOOTSTRAP_DEBUG_PARAMS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000"

    BOOTSTRAP_DIR_PARAMS="${BOOTSTRAP_LOG_PARAMS} ${BOOTSTRAP_PID_PARAMS} ${BOOTSTRAP_CONF_PARAMS}"

    run_nifi_cmd="'${JAVA}' -cp '${BOOTSTRAP_CLASSPATH}' -Xms12m -Xmx24m ${BOOTSTRAP_DIR_PARAMS} ${BOOTSTRAP_DEBUG_PARAMS} ${BOOTSTRAP_JAVA_OPTS} org.apache.nifi.bootstrap.RunNiFi $@"

    if [ -n "${run_as_user}" ]; then
      # 为运行提供SCRIPT_DIR并执行ni -env。
      run_nifi_cmd="sudo -u ${run_as_user} sh -c \"SCRIPT_DIR='${SCRIPT_DIR}' && . '${SCRIPT_DIR}/nifi-env.sh' && ${run_nifi_cmd}\""
    fi

    if [ "$1" = "run" ]; then
      # 使用exec将PID切换到RunNiFi java进程,而不是将其作为子进程( 前台运行nifi,Ctrl-C就停止NIFI)
      # exec命令 用于调用并执行指令的命令。exec命令通常用在shell脚本程序中,可以调用其他的命令。如果在当前终端中使用命令,则当指定的命令执行完毕后会立即退出终端。
      run_nifi_cmd="exec ${run_nifi_cmd}"
    fi
    # Linux eval命令用于重新运算求出参数的内容。
    # eval可读取一连串的参数,然后再依参数本身的特性来执行。
    if [ "$1" = "start" ]; then
        ( eval "cd ${NIFI_HOME} && ${run_nifi_cmd}" & )> /dev/null 1>&-
    else
        eval "cd ${NIFI_HOME} && ${run_nifi_cmd}"
    fi
    EXIT_STATUS=$?

   # 稍等(3秒),等待日志记录完成,然后回显新行。
   # 我们这样做是为了避免在运行命令后,日志在控制台被吐出来,然后返回给用户
    sleep 3
    echo
}

main() {
    init "$1"
    run "$@"
}

# ==========================
# 方法区 end
# ==========================

# ==========================
# 3、入口 start
# ==========================

# 判断 $1 第一个参数是什么
# 其中install 将nifi安装为service
# start 启动
# stop 停止
# run
# status
# dump
# env
# restart 重启

# $@ 传全部参数
case "$1" in
    install)
        install "$@"
        ;;
    start|stop|run|status|dump|env)
        main "$@"
        ;;
    restart)
        init
        run "stop"
        run "start"
        ;;
    *)
        echo "Usage nifi {start|stop|run|restart|status|dump|install}"
        ;;
esac
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Panda诚 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档