title: nifi.sh 脚本解读
date: 2020-05-21
categories:
- Apache NIFI
tags: - Apache NIFI
author: 张诚
location: BeiJing
publish: true
sticky:
整个脚本分为三部分,第一部分是确定NIFI各个路径 目录的确定,设置环境变量,第二部分是方法区。第三部分是脚本逻辑代码的入口,初略的根据传参不同区执行不同的方法。以下脚本有详细注释:
#!/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.shTARGET_FILE=$(basename $TARGET_FILE)## 遍历(可能的)符号链接链 -L filename,判断文件是否问链接文件while [ -L "$TARGET_FILE" ]doTARGET_FILE=$(readlink $TARGET_FILE)cd $(dirname $TARGET_FILE)TARGET_FILE=$(basename $TARGET_FILE)done# pwd -P 显示出实际路径,而非使用连接(link)路径。PHYS_DIR=$(pwd -P)# 脚本所在目录SCRIPT_DIR=$PHYS_DIRPROGNAME=$(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)" inCYGWIN*)cygwin=true;;AIX*)aix=true;;OS400*)os400=true;;Darwin)darwin=true;;esac# For AIX, set an environment variableif ${aix}; thenexport LDR_CNTRL=MAXDATA=0xB0000000@DSAecho ${LDR_CNTRL}fi# In addition to those, go around the linux space and query the widely# adopted /etc/os-release to detect linux variantsif [ -f /etc/os-release ]; then. /etc/os-releasefi}unlimitFD() {# Use the maximum available, or set MAX_FD != -1 to use that# 判断 ${MAX_FD}有没有被赋值 条件成立则没有赋值if [ "x${MAX_FD}" = "x" ]; thenMAX_FD="maximum"fi# 如果可能的话,提升文件描述符的最大数量if [ "${os400}" = "false" ] && [ "${cygwin}" = "false" ]; thenMAX_FD_LIMIT=$(ulimit -H -n)if [ "${MAX_FD_LIMIT}" != 'unlimited' ]; thenif [ $? -eq 0 ]; thenif [ "${MAX_FD}" = "maximum" -o "${MAX_FD}" = "max" ]; then# use the system maxMAX_FD="${MAX_FD_LIMIT}"fiulimit -n ${MAX_FD} > /dev/null# echo "ulimit -n" `ulimit -n`if [ $? -ne 0 ]; thenwarn "Could not set maximum file descriptor limit: ${MAX_FD}"fielsewarn "Could not query system maximum file descriptor limit: ${MAX_FD_LIMIT}"fififi}# 找到要执行的JVMlocateJava() {# 设置Java虚拟机if $cygwin ; then[ -n "${JAVA}" ] && JAVA=$(cygpath --unix "${JAVA}")[ -n "${JAVA_HOME}" ] && JAVA_HOME=$(cygpath --unix "${JAVA_HOME}")fiif [ "x${JAVA}" = "x" ] && [ -r /etc/gentoo-release ] ; thenJAVA_HOME=$(java-config --jre-home)fiif [ "x${JAVA}" = "x" ]; thenif [ "x${JAVA_HOME}" != "x" ]; thenif [ ! -d "${JAVA_HOME}" ]; thendie "JAVA_HOME is not valid: ${JAVA_HOME}"fiJAVA="${JAVA_HOME}/bin/java"elsewarn "JAVA_HOME not set; results may vary"JAVA=$(type java)JAVA=$(expr "${JAVA}" : '.* \(/.*\)$')if [ "x${JAVA}" = "x" ]; thendie "java command not found"fififi# 如果命令是 env, tools.jar classes.jar也加到 classpathif [ "$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" ]; thenwarn "Could not locate tools.jar or classes.jar. Please set manually to avail all command features."fifi}# 初始化init() {# 确定是否需要执行特殊的操作系统处理detectOS# 如果可能的话,不限制文件描述符的数量unlimitFD# 找到要执行的JVMlocateJava "$1"}# 将nifi安装为serviceinstall() {detectOSif [ "${darwin}" = "true" ] || [ "${cygwin}" = "true" ]; thenecho 'Installing Apache NiFi as a service is not supported on OS X or Cygwin.'exit 1fiSVC_NAME=nifiif [ "x$2" != "x" ] ; thenSVC_NAME=$2fi# 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}" ]; thenecho "Current user does not have write permissions to ${initd_dir}. Cannot install NiFi as a service."exit 1fi# Create the init script, overwriting anything currently presentcat <<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 executableNIFI_HOME=${NIFI_HOME}bin_dir=\${NIFI_HOME}/binnifi_executable=\${bin_dir}/nifi.sh\${nifi_executable} "\$@"SERVICEDESCRIPTORif [ ! -f "${SVC_FILE}" ]; thenecho "Could not create service file ${SVC_FILE}"exit 1fi# Provide the user execute access on the filechmod u+x ${SVC_FILE}# If SLES or OpenSuse...if [ "${ID}" = "opensuse" ] || [ "${ID}" = "sles" ]; thenrm -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 approachelserm -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)" ]; thenunset run_as_userfiif $cygwin; thenif [ -n "${run_as_user}" ]; thenecho "The run.as option is not supported in a Cygwin environment. Exiting."exit 1fi;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}" ]; thenTOOLS_JAR=$(cygpath --path --windows "${TOOLS_JAR}")BOOTSTRAP_CLASSPATH="${TOOLS_JAR};${BOOTSTRAP_CLASSPATH}"fielseif [ -n "${run_as_user}" ]; thenif ! id -u "${run_as_user}" >/dev/null 2>&1; thenecho "The specified run.as user ${run_as_user} does not exist. Exiting."exit 1fifi;BOOTSTRAP_CLASSPATH="${BOOTSTRAP_CONF_DIR}:${BOOTSTRAP_LIBS}"if [ -n "${TOOLS_JAR}" ]; thenBOOTSTRAP_CLASSPATH="${TOOLS_JAR}:${BOOTSTRAP_CLASSPATH}"fifiechoecho "Java home: ${JAVA_HOME}"echo "NiFi home: ${NIFI_HOME}"echoecho "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}\""fiif [ "$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>&-elseeval "cd ${NIFI_HOME} && ${run_nifi_cmd}"fiEXIT_STATUS=$?# 稍等(3秒),等待日志记录完成,然后回显新行。# 我们这样做是为了避免在运行命令后,日志在控制台被吐出来,然后返回给用户sleep 3echo}main() {init "$1"run "$@"}# ==========================# 方法区 end# ==========================# ==========================# 3、入口 start# ==========================# 判断 $1 第一个参数是什么# 其中install 将nifi安装为service# start 启动# stop 停止# run# status# dump# env# restart 重启# $@ 传全部参数case "$1" ininstall)install "$@";;start|stop|run|status|dump|env)main "$@";;restart)initrun "stop"run "start";;*)echo "Usage nifi {start|stop|run|restart|status|dump|install}";;esac
公众号
关注公众号 得到第一手文章/文档更新推送。

