ActiveMQ 配置启动文件介绍

1.配置jdk环境(Linux)

一般在普通用户下的 ~/.bash_profile 或者在 /etc/profile 最后添加如下语句:

export JAVA_HOME=/opt/app/jdk1.8.0_162/
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib 
export PATH=${JAVA_HOME}/bin:$PATH

 

2.配置文件

activemq.xml

ActiveMQ的主配置文件,其中有部分配置有所修改以适应我的程序。





    
    
        
            file:${activemq.conf}/credentials.properties
        
    

   
    
    

    


    
    

        
        
            
              
                
                
                    
                  
                    
                  
                
                
                
                  
                   
                  
                
              
            
        


        
        
            
        

        
	
    
	
  	  
	

          
          
            
                
                    
                
                
                    
                
                
                    
                
            
        

        
        
            
              
            
            
            
        

        
        
            
        

    

  
  
    
    
    
    
    
    
  

    
    
    
    


通配符

  • . 用于在路径中分隔名称
  • * 用于匹配路径中的任何名称
  • > 用于递归地匹配从这个名称开始的任何目的地

关于通配符详细参见:http://activemq.apache.org/wildcards.html

 

jetty-realm.properties

定义可以访问web(console,demo等)的用户密码[角色]。

一般要修改默认的密码,或者防火墙关闭8161端口禁止访问。

# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: admin, admin
user: user, user

 

jmx.access 和 jmx.password

配置jmx访问的账户密码

 

3.启动脚本 activemq

位于:apache-activemq-5.11.1/bin/

 

3.1 INIT INFO 系统服务脚本头

activemq通过命令 activemq start 启动之后,以系统服务的方式在后台运行。

以下是脚本的开头,这个是系统服务系统的方式

#!/bin/sh

### BEGIN INIT INFO
# Provides:          activemq
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     3 5
# Default-Stop:      0 1 6
# Short-Description: Starts ActiveMQ
# Description:       Starts ActiveMQ Message Broker Server
### END INIT INFO

定义两个变量,分别记录命令行的所有参数和执行选项。

# ------------------------------------------------------------------------
# IMPROVED DEBUGGING (execute with bash -x)
# export PS4=' ${BASH_SOURCE}:${LINENO}(${FUNCNAME[0]}) '
#
# Backup invocation parameters
COMMANDLINE_ARGS="$@"
EXEC_OPTION=""

 

3.2 几个帮助函数

setCurrentUser()用于将当前用户赋值给CUSER变量,以便脚本里使用。

# ------------------------------------------------------------------------
# HELPERS

# a simple helper to get the current user
setCurrentUser(){
   CUSER="`whoami 2>/dev/null`"
   # Solaris hack
   if [ ! $? -eq 0 ]; then
      CUSER="`/usr/ucb/whoami 2>/dev/null`"
   fi
}

pathCanonical()用于获得规范的路径,摒除系统的差异。

# get a canonical path, macosx and slowlaris does not support radlink -f :-)
pathCanonical() {
    local dst="${1}"
    while [ -h "${dst}" ] ; do
        ls=`ls -ld "${dst}"`
        link=`expr "$ls" : '.*-> \(.*\)$'`
        if expr "$link" : '/.*' > /dev/null; then
            dst="$link"
        else
            dst="`dirname "${dst}"`/$link"
        fi
    done
    local bas="`basename "${dst}"`"
    local dir="`dirname "${dst}"`"
    if [ "$bas" != "$dir" ]; then
      dst="`pathCanonical "$dir"`/$bas"
    fi
    echo "${dst}" | sed -e 's#//#/#g' -e 's#/\./#/#g' -e 's#/[^/]*/\.\./#/#g'
}

getActiveMQHome() 用于获取ActiveMQ的安装路径。先通过pathCanonical()获取到启动脚本的bin路径,再获取到上一级的home目录。pwd的选项-P,是为了避免所有的符号链接。

# a simple helper to get the activemq installation dir
getActiveMQHome(){
  # get the real path to the binary
  local REAL_BIN="`pathCanonical $0`"
  local REAL_DIR="`dirname $REAL_BIN`/../"
  REAL_DIR="`cd $REAL_DIR && pwd -P`"
  if [ -z "$REAL_DIR" ];then
      echo 'ERROR: unable to find real installtion path fo activemq, you have to define ACTIVEMQ_HOME manually in the config' >&2
      exit 1
  fi
  echo "$REAL_DIR/"

}

 

3.3 几个帮助判断

配置MQ的安装目录,如果脚本启动之前的环境里没有定义ACTIVEMQ_HOME变量,则将getActiveMQHome函数获取到的路径赋值给它。

base目录,如果环境历里设置了ACTIVEMQ_BASE变量则用之,否则将ACTIVEMQ_HOME赋值给她。

# Active MQ installation dir
if [ -z "$ACTIVEMQ_HOME" ] ; then
  ACTIVEMQ_HOME="`getActiveMQHome`"
fi

# Active MQ base dir
if [ -z "$ACTIVEMQ_BASE" ] ; then
  ACTIVEMQ_BASE="$ACTIVEMQ_HOME"
fi

先配置用户级的classpath,脚本这里使用或者脚本外部调用。

再配置MQ的classpath,将外部lib添加到ACTIVEMQ_USER_CLASSPATH之前,合起来作为ACTIVEMQ_CLASSPATH。

# Configure user specified classpath here or externally using this variable
if [ -z "$ACTIVEMQ_USER_CLASSPATH" ] ; then
    ACTIVEMQ_USER_CLASSPATH=""
fi

# ActiveMQ Classpath configuration
ACTIVEMQ_CLASSPATH="$ACTIVEMQ_BASE/../lib/:$ACTIVEMQ_USER_CLASSPATH"

MQ配置文件目录,如果变量ACTIVEMQ_CONF未配置,且老的写法ACTIVEMQ_CONFIG_DIR也未配置,则将$ACTIVEMQ_BASE/conf赋值给它。

# Active MQ configuration directory
if [ -z "$ACTIVEMQ_CONF" ] ; then

    # For backwards compat with old variables we let ACTIVEMQ_CONFIG_DIR set ACTIVEMQ_CONF
    if [ -z "$ACTIVEMQ_CONFIG_DIR" ] ; then
        ACTIVEMQ_CONF="$ACTIVEMQ_BASE/conf"
    else
        ACTIVEMQ_CONF="$ACTIVEMQ_CONFIG_DIR"
    fi
fi

MQ可以配置一个非root权限的用户,如果ACTIVEMQ_USER变量没有指定,则不改变,默认为当前用户。

# Configure a user with non root privileges, if no user is specified do not change user
if [ -z "$ACTIVEMQ_USER" ] ; then
    ACTIVEMQ_USER=""
fi

MQ的数据目录,持久化目录,也存储了log。

如果ACTIVEMQ_DATA变量未指定,且老写法ACTIVEMQ_DATA_DIR也未指定,则将$ACTIVEMQ_BASE/data赋值给ACTIVEMQ_DATA。

# Active MQ data directory
if [ -z "$ACTIVEMQ_DATA" ] ; then

    # For backwards compat with old variables we let ACTIVEMQ_DATA_DIR set ACTIVEMQ_DATA
    if [ -z "$ACTIVEMQ_DATA_DIR" ] ; then
        ACTIVEMQ_DATA="$ACTIVEMQ_BASE/data"
    else
        ACTIVEMQ_DATA="$ACTIVEMQ_DATA_DIR"
    fi
fi

MQ的tmp目录

if [ -z "$ACTIVEMQ_TMP" ] ; then
  ACTIVEMQ_TMP="$ACTIVEMQ_BASE/tmp"
fi

如果$ACTIVEMQ_DATA目录不存在,则将当前用户保存到CUSER变量。

     如果$ACTIVEMQ_USER不为空或者$ACTIVEMQ_USER与$CUSER相同,则直接创建该目录;

     或者如果当前用户id等于0(即root的id),则需要使用指定用户$ACTIVEMQ_USER的权限来创建该目录。

if [ ! -d "$ACTIVEMQ_DATA" ]; then
   setCurrentUser
   if ( [ -z "$ACTIVEMQ_USER" ] || [ "$ACTIVEMQ_USER" = "$CUSER" ] );then
        mkdir $ACTIVEMQ_DATA
   elif [ "`id -u`" = "0" ];then
      su -c "mkdir $ACTIVEMQ_DATA" - $ACTIVEMQ_USER;
   fi
fi

MQ的PID文件路径

# Location of the pidfile
if [ -z "$ACTIVEMQ_PIDFILE" ]; then
  ACTIVEMQ_PIDFILE="$ACTIVEMQ_DATA/activemq.pid"
fi

上面的是一些基础环境的获取,下面介绍配置的加载。

 

3.4 加载配置

对于使用实例时的加载,一般没用到。我就说没有实例时,配置文件的路径ACTIVEMQ_CONFIGS有多个,分别是"/etc/default/activemq","$HOME/.activemqrc","$ACTIVEMQ_HOME/bin/env"。

# ------------------------------------------------------------------------
# LOAD CONFIGURATION

# CONFIGURATION
# For using instances
if ( basename $0 | grep "activemq-instance-" > /dev/null);then
  INST="`basename $0|sed 's/^activemq-instance-//;s/\.sh$//'`"
  ACTIVEMQ_CONFIGS="/etc/default/activemq-instance-${INST} $HOME/.activemqrc-instance-${INST}"
  echo "INFO: Using alternative activemq configuration files: $ACTIVEMQ_CONFIGS"
else
  ACTIVEMQ_CONFIGS="/etc/default/activemq $HOME/.activemqrc $ACTIVEMQ_HOME/bin/env"
fi

加载activemq配置,先将标志CONFIG_LOAD设置为no。

遍历$ACTIVEMQ_CONFIGS里面的配置,一般只有env是存在的,env是个shell脚本,可在里面修改一些配置,里面的配置将会覆盖启动脚本里获取到的配置。

( . $ACTIVEMQ_CONFIG >/dev/null 2>&1 )  执行之后,判断状态码,为0则再次执行  .  $ACTIVEMQ_CONFIG ,并将标志CONFIG_LOAD设置为yes 。关于使用点加脚本的方式执行的说明,参见附录1。

# load activemq configuration
CONFIG_LOAD="no"
for ACTIVEMQ_CONFIG in $ACTIVEMQ_CONFIGS;do
   if [ -f "$ACTIVEMQ_CONFIG" ] ; then
     ( . $ACTIVEMQ_CONFIG >/dev/null 2>&1 )
     if [ "$?" != "0" ];then
      echo "ERROR: There are syntax errors in '$ACTIVEMQ_CONFIG'"
      exit 1
     else
       echo "INFO: Loading '$ACTIVEMQ_CONFIG'"
       . $ACTIVEMQ_CONFIG
      CONFIG_LOAD="yes"
      break
     fi
   fi
done

执行上面这个程序后,在启动脚本的环境下的变量里多了如下一些变量(可通过set命令查看)

ACTIVEMQ_CONFIG=/opt/app/apache-activemq-5.11.1/bin/env
ACTIVEMQ_KILL_MAXSECONDS=30
ACTIVEMQ_OPTS='-Xms1G -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=/login.config'
ACTIVEMQ_OPTS_MEMORY='-Xms1G -Xmx1G'
ACTIVEMQ_QUEUEMANAGERURL='--amqurl tcp://localhost:61616'
ACTIVEMQ_SSL_OPTS=
ACTIVEMQ_SUNJMX_CONTROL=
ACTIVEMQ_SUNJMX_START=' -Dcom.sun.management.jmxremote'
ACTIVEMQ_USER=
JAVACMD=/opt/app/jdk1.8.0_162/bin/java

通过标志变量CONFIG_LOAD值为yes来通知加载了默认配置。

# inform user that default configuration is loaded, no suitable configfile found
if [ "$CONFIG_LOAD" != "yes" ];then
      echo "INFO: Using default configuration";
      echo "      Configurations are loaded in the following order: $ACTIVEMQ_CONFIGS"
      echo
fi

设置变量ACTIVEMQ_OPTS

(ACTIVEMQ_OPTS和ACTIVEMQ_OPTS_MEMORY都可以在env脚本里设置)

if [ -z "$ACTIVEMQ_OPTS" ] ; then
    ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config"
fi

 

3.5 针对不同操作系统的适配

其他也写java项目,如tomcat的启动脚本里面也有类似的内容。

我的环境是linux系统,所以这些内容都不会执行到。

# ------------------------------------------------------------------------
# OS SPECIFIC SUPPORT

OSTYPE="unknown"

case "`uname`" in
  CYGWIN*) OSTYPE="cygwin" ;;
  Darwin*)
           OSTYPE="darwin"
           if [ -z "$JAVA_HOME" ] && [ "$JAVACMD" = "auto" ];then
             JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
           fi
           ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched
if [ "$OSTYPE" = "cygwin" ]; then
  [ -n "$ACTIVEMQ_HOME" ] &&
    ACTIVEMQ_HOME="`cygpath --unix "$ACTIVEMQ_HOME"`"
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`cygpath --unix "$JAVA_HOME"`"
  [ -n "$ACTIVEMQ_CLASSPATH" ] &&
    ACTIVEMQ_CLASSPATH="`cygpath --path --unix "$ACTIVEMQ_CLASSPATH"`"
fi

 

3.6 寻找java命令的路径

JAVACMD从env脚本继承而来值为"auto"。

如果JAVACMD为空或者等于"auto",则

        如果JAVA_HOME非空(我们一般在配置jdk环境的时候就指定了JAVA_HOME),则

                如果 "$JAVA_HOME/jre/sh/java" 可执行,则将其赋值给JAVACMD;否则将"$JAVA_HOME/bin/java"赋值给他。

                一般jdk里jre/bin下没有sh目录,所以一般找到的就是$JAVA_HOME/bin/java。

# Detect the location of the java binary
if [ -z "$JAVACMD" ] || [ "$JAVACMD" = "auto" ] ; then
  if [ -n "$JAVA_HOME"  ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
    else
      JAVACMD="$JAVA_HOME/bin/java"
    fi
  fi
fi

如果还是没有找到java的位置,则使用which命令来查找java。如果找到了,则代表环境变量里找得到java,JAVACMD就直接使用java。

# Hm, we still do not know the location of the java binary
if [ -z "$JAVACMD" ] || [ "$JAVACMD" = "auto" ] || [ ! -x "$JAVACMD" ] ; then
    JAVACMD=`which java 2> /dev/null `
    if [ -z "$JAVACMD" ] ; then
        JAVACMD=java
    fi
fi

如果$JAVACMD 还不存在或不可执行,就报错,退出进程。

# Stop here if no java installation is defined/found
if [ ! -x "$JAVACMD" ] ; then
  echo "ERROR: Configuration variable JAVA_HOME or JAVACMD is not defined correctly."
  echo "       (JAVA_HOME='$JAVA_HOME', JAVACMD='$JAVACMD')"
  exit 1
fi

如果$JAVACMD可执行,就跳过上一个判断,向终端的标准输出打印使用的$JAVACMD。

echo "INFO: Using java '$JAVACMD'"

如果经过前面的配置,$ACTIVEMQ_BASE还是为空,则把$ACTIVEMQ_HOME赋值给它。

if [ -z "$ACTIVEMQ_BASE" ] ; then
  ACTIVEMQ_BASE="$ACTIVEMQ_HOME"
fi

如果是在windows下的cygwin环境中启动的本脚本,则在相应的变量前添加"cygpath --windows"前缀。

# For Cygwin, switch paths to Windows format before running java if [ "$OSTYPE" = "cygwin" ]; then
if [ "$OSTYPE" = "cygwin" ];then
  ACTIVEMQ_HOME="`cygpath --windows "$ACTIVEMQ_HOME"`"
  ACTIVEMQ_BASE="`cygpath --windows "$ACTIVEMQ_BASE"`"
  ACTIVEMQ_CONF="`cygpath --windows "$ACTIVEMQ_CONF"`"
  ACTIVEMQ_DATA="`cygpath --windows "$ACTIVEMQ_DATA"`"
  ACTIVEMQ_CLASSPATH=`cygpath --path --windows "$ACTIVEMQ_CLASSPATH"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`cygpath --windows "$JAVA_HOME"`"
  CYGHOME="`cygpath --windows "$HOME"`"
  ACTIVEMQ_TMP="`cygpath --windows "$ACTIVEMQ_TMP"`"
  if [ -n "$CYGHOME" ]; then
      ACTIVEMQ_CYGWIN="-Dcygwin.user.home=\"$CYGHOME\""
  fi
fi

 

3.7 设置默认cpasspath

在AMQ的安装配置目录前添加实例配置目录,以便先获取实例的相关配置。

# Set default classpath
# Add instance conf dir before AMQ install conf dir to pick up instance-specific classpath entries first
ACTIVEMQ_CLASSPATH="${ACTIVEMQ_CONF}:${ACTIVEMQ_CLASSPATH}"

如果系统是cygwin,则删除反斜杠以防止引用问题。

if [ "$OSTYPE" = "cygwin" ];then
  # remove training backslashes to prevent quoting problems
  ACTIVEMQ_CLASSPATH="`echo ${ACTIVEMQ_CLASSPATH}|sed '~s,[\\]*$,,g'`"
  ACTIVEMQ_HOME="`echo ${ACTIVEMQ_HOME}|sed '~s,[\\]*$,,g'`"
  ACTIVEMQ_BASE="`echo ${ACTIVEMQ_BASE}|sed '~s,[\\]*$,,g'`"
  ACTIVEMQ_CONF="`echo ${ACTIVEMQ_CONF}|sed '~s,[\\]*$,,g'`"
  ACTIVEMQ_DATA="`echo ${ACTIVEMQ_DATA}|sed '~s,[\\]*$,,g'`"
fi

 

3.8 功能:启动AMQ的jar文件

@ARG1 :pid文件名,如果本参数指定了,函数invokeJar()启动的java进程将在后台以服务的方式运行,并且这个文件存储着新建的进程pid。

              标准输出和错误输出都将被抑制。

@RET :出现错误则为0

注意:本函数使用了许多全局定义的变量。

-  如果$ACTIVEMQ_USER设置了,本函数就尝试使用指定的用户启动进程。

3.8.1 函数:invokeJar()

如果${ACTIVEMQ_HOME}/bin/activemq.jar 不存在则报错,存在则继续。

然后调用函数setCurrentUser设置当前用户给变量$CUSER。

如果$ACTIVEMQ_USER为空或者等于当前用户$CUSER,则添加前缀"sh -c "和后缀";";

再如果id为0,即root,就要使用指定用户的前缀"su -s /bin/sh -c "和后缀" - $ACTIVEMQ_USER",然后向终端输出提示信息,告知更改了执行用户。

然后才是执行java程序。

【条件一】

如果$TASK_TODO(本函数的第二个参数)非空并且不等于stop,则

       如果$ACTIVEMQ_OUT(继承自env脚本)为空,则赋值为"/dev/null"。(其实env里面就已经这样判断并赋值了,为什么这里还要来一遍??)

       还记得最开始的EXEC_OPTION变量吗,为空。这里以它为开头,从$DOIT_PREFIX到$DOIT_POSTFIX这一句才是真正的执行启动AMQ的jar的语句。

       然后用RET变量来保存执行结束状态。

【条件二】

再如果$TASK_TODO非空且等于stop,则

       用SPID变量来保存本函数的第一个参数${PIDFILE}的值。

       然后也是真正的意义上的启动语句。

       并用RET来保存结束状态。

【条件三】

否则

       执行并保存结束状态。

函数的最后是返回变量$RET。

我们需要注意区分上面红色字体的三个条件下的启动参数间的差异。

# Start the ActiveMQ JAR
#
#
# @ARG1 : the name of the PID-file
#         If specified, this function starts the java process in background as a daemon
#         and stores the pid of the created process in the file.
#         Output on stdout/stderr will be supressed if this parameter is specified
# @RET  : If unless 0 something went wrong
#
# Note: This function uses a lot of globally defined variables
# - if $ACTIVEMQ_USER is set, the function tries starts the java process whith the specified user
invokeJar(){
   PIDFILE="$1"
   TASK_TODO="$2"
   RET="1"

   if [ ! -f "${ACTIVEMQ_HOME}/bin/activemq.jar" ];then
    echo "ERROR: '${ACTIVEMQ_HOME}/bin/activemq.jar' does not exist, define ACTIVEMQ_HOME in the config"
    exit 1
   fi

   setCurrentUser

   if ( [ -z "$ACTIVEMQ_USER" ] || [ "$ACTIVEMQ_USER" = "$CUSER" ] );then
      DOIT_PREFIX="sh -c "
      DOIT_POSTFIX=";"
   elif [ "`id -u`" = "0" ];then
      DOIT_PREFIX="su -s /bin/sh -c "
      DOIT_POSTFIX=" - $ACTIVEMQ_USER"
      echo "INFO: changing to user '$ACTIVEMQ_USER' to invoke java"
   fi

   # Execute java binary
   if [ -n "$TASK_TODO" ] && [ "$TASK_TODO" != "stop" ];then
      if [ -z "$ACTIVEMQ_OUT" ]; then
         ACTIVEMQ_OUT="/dev/null"
      fi
      $EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
              -Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
              -Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
              -Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
              -Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
              -Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
              $ACTIVEMQ_CYGWIN \
              -jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS >> $ACTIVEMQ_OUT 2>&1 &
              RET=\"\$?\"; APID=\"\$!\";
              echo \$APID > "${PIDFILE}";
              echo \"INFO: pidfile created : '${PIDFILE}' (pid '\$APID')\";exit \$RET" $DOIT_POSTFIX
      RET="$?"
   elif [ -n "$TASK_TODO" ] && [ "$TASK_TODO" = "stop" ];then
          SPID="`cat "${PIDFILE}"`"
          $EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
              -Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
              -Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
              -Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
              -Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
              -Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
              $ACTIVEMQ_CYGWIN \
              -jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS --pid $SPID &
              RET=\"\$?\"; APID=\"\$!\";
              echo \$APID > "${PIDFILE}.stop"; exit \$RET" $DOIT_POSTFIX
      RET="$?"
   else
      $EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
              -Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
              -Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
              -Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
              -Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
              -Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
              $ACTIVEMQ_CYGWIN \
              -jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS" $DOIT_POSTFIX
      RET="$?"
   fi
   return $RET
}

 

3.9 功能:检查ActiveMQ是否在运行

@RET : 0 => activemq 进程正在运行中

              1 => $ACTIVEMQ_PIDFILE中进程ID不存在了

              2 => PID文件相关错误

注意 : 本函数使用了全局定义的变量

- $ACTIVEMQ_PIDFILE : PID文件名称(全路径)

3.9.1 函数:checkRunning()

如果$ACTIVEMQ_PIDFILE文件存在,则

        如果$ACTIVEMQ_PIDFILE文件的值为空,则报错“PID文件存在但是不包含PID”。

        将$ACTIVEMQ_PIDFILE文件的值赋值给ACTIVEMQ_PID。

        ps -p 来探测该PID的进程是否存在,并用RET来保存,$RET不为0,则本函数return 0;$RET为0,则本函数return 1。

否则

        本函数return 1 。

# Check if ActiveMQ is running
#
# @RET  : 0 => the activemq process is running
#         1 => process id in $ACTIVEMQ_PIDFILE does not exist anymore
#         2 => something is wrong with the pid file
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file


checkRunning(){
    if [ -f "$ACTIVEMQ_PIDFILE" ]; then
       if  [ -z "`cat $ACTIVEMQ_PIDFILE`" ];then
        echo "ERROR: Pidfile '$ACTIVEMQ_PIDFILE' exists but contains no pid"
        return 2
       fi
       ACTIVEMQ_PID="`cat ${ACTIVEMQ_PIDFILE}`"
       RET="`ps -p "${ACTIVEMQ_PID}"|grep java`"   #ps -p 的用法见附录2
       if [ -n "$RET" ];then
         return 0;
       else
         return 1;
       fi
    else
         return 1;
    fi
}

3.9.2 函数:checkStopRunning()

AMQ在停止的时候,会启动一个进程来停止服务,本函数就是检测这个stop进程的状态。

stop进程产生的PID文件以".stop"结尾。相关逻辑判断与checkRunning函数类似。

checkStopRunning(){
    PID_STOP="${ACTIVEMQ_PIDFILE}.stop"
    if [ -f "$PID_STOP" ]; then
       if  [ -z "`cat $PID_STOP`" ];then
        echo "ERROR: Pidfile os stop process '$PID_STOP' exists but contains no pid"
        return 2
       fi
       THEPID=`cat ${PID_STOP}`
       RET=`ps -p $THEPID|grep java`
       if [ -n "$RET" ];then
         return 0;
       else
         return 1;
       fi
    else
         return 1;
    fi
}

 

3.10 功能:检查ActiveMQ是否运行

@RET : 0 => activemq进程运行

              1 => activemq进程没有运行

注意 : 本函数使用了全局定义的变量

- $ACTIVEMQ_PIDFILE : PID文件名称()全路径

调用checkRunning函数,判断函数结束状态,如果为0,则进程在运行,于是将文件$ACTIVEMQ_PIDFILE里保存值赋值给PID变量,并且以return 0 结束本函数。

3.10.1 函数 : invoke_status()

# Check if ActiveMQ is running
#
# @RET  : 0 => the activemq process is running
#         1 => the activemq process is not running
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file


invoke_status(){
    if ( checkRunning );then
         PID="`cat $ACTIVEMQ_PIDFILE`"
         echo "ActiveMQ is running (pid '$PID')"
         exit 0
    fi
    echo "ActiveMQ not running"
    exit 1
}

3.11 功能 : ActiveMQ如果没有运行则启动

@RET : 0 => 进程正在启动或者已经启动

              !0 => 出错

注意 : 本函数使用了全局定义的变量

- $ACTIVEMQ_PIDFILE                : PID文件名称()全路径

- $ACTIVEMQ_OPTS                    : 附加选项

- $ACTIVEMQ_SUNJMX_START  : JMX设定的选项

- $ACTIVEMQ_SSL_OPTS            : SSL加密相关的选项

调用checkRunning函数,判断函数结束状态,如果为0,则进程在运行,并打印信息到终端。

然后使用ACTIVEMQ_OPTS添加一些选项,

调用invokeJar函数,pid文件,start参数 启动AMQ进程。

这里的start是invokeJar函数的第二个参数,也就是前面说的该函数内部的TASK_TODO,且是执行jar文件的第一个条件情况(见前面红色字体部分)

3.11.1 函数 : invoke_start()

# Start ActiveMQ if not already running
#
# @RET  : 0 => is now started, is already started
#         !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE      : the name of the pid file
# - $ACTIVEMQ_OPTS         : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS     : options for SSL encryption

invoke_start(){
    if ( checkRunning );then
      PID="`cat $ACTIVEMQ_PIDFILE`"
      echo "INFO: Process with pid '$PID' is already running"
      exit 0
    fi

    ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SUNJMX_START $ACTIVEMQ_SSL_OPTS -Djava.awt.headless=true -Djava.io.tmpdir=\"${ACTIVEMQ_TMP}\""

    echo "INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details"
    invokeJar "$ACTIVEMQ_PIDFILE" start
    exit "$?"
}

3.12 功能 : 后台启动ActiveMQ(debug模式)

本函数以调试模式启动consle,方便观察输出。

@RET  :  0 => 启动

                1 => 已经启动

                !0 => 报错

注意 : 本函数使用了全局定义的变量

- $ACTIVEMQ_PIDFILE                : PID文件名称()全路径

- $ACTIVEMQ_OPTS                    : 附加选项

- $ACTIVEMQ_SUNJMX_START  : JMX设定的选项

- $ACTIVEMQ_SSL_OPTS            : SSL加密相关的选项

调用checkRunning函数检查进程状态,没有运行才继续下去。

同样要添加一些选项到ACTIVEMQ_OPTS。

COMMANDLINE_ARGS是传递给启动脚本的,

3.12.1 函数 : invoke_console()

在前台运行AMQ,通常用于调试。

@RET  :   0 =>  was started

                 1 =>  was already started    (我去,"was started"和"was already started "怎么区分开,英语不好)

                 !0 => 出错     (我想问,上面1不也是非0吗,不属于这一类?)

注意 : 本函数使用了全局定义的变量

- $ACTIVEMQ_PIDFILE                : PID文件名称()全路径

- $ACTIVEMQ_OPTS                    : 附加选项

- $ACTIVEMQ_SUNJMX_START  : JMX设定的选项

- $ACTIVEMQ_SSL_OPTS            : SSL加密相关的选项

在函数invoke_console中

如果 checkRunning 为真,则打印错误,告诉AMQ已经在运行,并退出函数。

ACTIVEMQ_OPTS追加一些内容。

COMMANDLINE_ARGS  删除以console开头的字段。

EXEC_OPTION赋值为"exec"。

打印一些 INFO 。

保存当前shell进程的PID到文件 $ACTIVEMQ_PIDFILE 。

以文件$ACTIVEMQ_PIDFILE作为参数执行函数invokeJar,也就是使用启动脚本的PID来最为新启动的jar进程的PID。在前面该函数的开头有说明。

使用变量 RET 记录invokeJar函数退出状态。

打印  INFO : 移除PID文件 $ACTIVEMQ_PIDFILE。

最后再以前面invokeJar函数退出状态最为本函数的退出状态。

# Start ActiveMQ in foreground (for debugging)
#
# @RET  : 0 => was started
#         1 => was already started
#         !0 => somthing went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE      : the name of the pid file
# - $ACTIVEMQ_OPTS         : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS     : options for SSL encryption

invoke_console(){
    if ( checkRunning );then
      echo "ERROR: ActiveMQ is already running"
      exit 1
    fi

    ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SUNJMX_START $ACTIVEMQ_SSL_OPTS -Djava.awt.headless=true -Djava.io.tmpdir=\"${ACTIVEMQ_TMP}\""

    COMMANDLINE_ARGS="start `echo $COMMANDLINE_ARGS|sed 's,^console,,'`"
    EXEC_OPTION="exec"
    echo "INFO: Starting in foreground, this is just for debugging purposes (stop process by pressing CTRL+C)"
    echo "INFO: Creating pidfile $ACTIVEMQ_PIDFILE"
    echo "$$" > "$ACTIVEMQ_PIDFILE"
    invokeJar "$ACTIVEMQ_PIDFILE"
    RET="$?"
    echo "INFO: removing pidfile $ACTIVEMQ_PIDFILE"
    exit "$RET"
}

 

3.13 功能 : Kill ActiveMQ

杀死 ActiveMQ

3.13.1 函数 : invoke_kill()

kill ActiveMQ 进程。

@RET  :  0 => 成功停止

                !0 => 停止失败

注意 : 本函数使用了全局定义的变量

- $ACTIVEMQ_PIDFILE                : PID文件名称()全路径

在函数invoke_kill中

如果 checkRunning 为真,则

        将文件${ACTIVEMQ_PIDFILE}中的PID号赋值给变量ACTIVEMQ_PID

        打印提示信息,已经发送SIGKILL信号到该PID进程。

        真正执行kill命令。"kill -KILL"与"kill -9"等价。强制杀死进程。

        记录kill命令退出状态。

        强制删除文件 ${ACTIVEMQ_PIDFILE} 。

        以kill的退出状态最为本函数的退出状态。

否则

        打印 INFO,没有运行,什么也不做。

        以0退出本函数。

# Kill ActiveMQ
# @RET    : 0 => stop was successful
#          !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE         : the name of the pid file


invoke_kill(){
    if ( checkRunning ); then
       ACTIVEMQ_PID="`cat ${ACTIVEMQ_PIDFILE}`"
       echo "INFO: sending SIGKILL to pid '$ACTIVEMQ_PID'"
       kill -KILL $ACTIVEMQ_PID
       RET="$?"
       rm -f "${ACTIVEMQ_PIDFILE}"
       return $RET
    fi
    echo "INFO: not running, nothing to do"
    return 0
}

 

3.14 功能 : Stop ActiveMQ

停止 ActiveMQ

3.14.1 函数 : invoke_stop()

停止 ActiveMQ 进程。(这个stop和前面的kill,不都是停止么?)

@RET     :   0 => 停止成功

                    !0 => 停止失败

注意 : 本函数使用了全局定义的变量

- $ACTIVEMQ_PIDFILE                      : PID文件名称()全路径

- $ACTIVEMQ_KILL_MAXSECONDS : 一个秒为单位的数字,是在jmx接口发送shutdonw信号后,broker停止所耗费的时间。

在函数invoke_stop中

首先把RET置为1。

如果 checkRunning 为真,则

        opts后面追加ssl的opts。

        COMMANDLINE_ARGS后面追加ACTIVEMQ_SUNJMX_CONTROL。

        文件$ACTIVEMQ_PIDFILE里的PID号赋值给变量ACTIVEMQ_PID。

        以两个参数"$ACTIVEMQ_PIDFILE" "stop" 来执行函数 invokeJar。

        保存invokeJar执行退出状态。

        把FOUND置为0,i置为0.

        打印 INFO, 等待至少 $ACTIVEMQ_KILL_MAXSECONDS秒的常规进程停止操作。

        当  $i 小于或等于 $ACTIVEMQ_KILL_MAXSECONDS 时,则

               如果 checkStopRunning 不为真,则

                        如果 checkRunning 不为真,则

                                打印完成 并把 FOUND置为1。

                        否则

                                break退出循环。

       

               如果 checkRunning 为真,则

                        休眠1秒,并打印一个"."号。

               否则

                       打印TERMINATED,并把FOUND置为1。

 

               变量i加1。

       

        如果 FOUND不为1,则

               打印 INFO,常规停止不成功,发送SIGKILL信号到jar进程。

                执行函数invoke_kill。 (这里我们可以看出,invoke_stop函数是完整的停止操作,而invoke_kill函数是常规停止操作失败而强制杀死进程的擦做)

               保存invoke_kill函数的退出状态。

再如果 "$ACTIVEMQ_PIDFILE" 文件存在,则

        打印错误,没有或者过期PID号在文件 "$ACTIVEMQ_PIDFILE"里。

        打印INFO,移除文件"$ACTIVEMQ_PIDFILE"。

否则,

        打印 ActiveMQ没有运行。

        以0退出本函数。

 

删除文件"$ACTIVEMQ_PIDFILE"和"$ACTIVEMQ_DATA/stop.pid"。

最后用前面的RET来退出本函数。

# Stop ActiveMQ
# @RET    : 0 => stop was successful
#          !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE         : the name of the pid file
# - $ACTIVEMQ_KILL_MAXSECONDS : the number of seconds to wait for termination of broker after sending
#                              shutdown signal by jmx interface

invoke_stop(){
    RET="1"
    if ( checkRunning );then
       ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SSL_OPTS"
       COMMANDLINE_ARGS="$COMMANDLINE_ARGS $ACTIVEMQ_SUNJMX_CONTROL"

       ACTIVEMQ_PID="`cat $ACTIVEMQ_PIDFILE`"

       invokeJar "$ACTIVEMQ_PIDFILE" "stop"
       RET="$?"

       FOUND="0"
       i=0
       echo "INFO: Waiting at least $ACTIVEMQ_KILL_MAXSECONDS seconds for regular process termination of pid '$ACTIVEMQ_PID' : "
       while [ "$i" -le "$ACTIVEMQ_KILL_MAXSECONDS" ]; do
         if [ ! checkStopRunning ];then
            if [ ! checkRunning ]; then
               echo " FINISHED"
               FOUND="1"
            fi
            break
         fi

         if (checkRunning);then
            sleep 1
            printf  "."
         else
            echo " TERMINATED"
            FOUND="1"
            break
         fi
         i="`expr $i + 1`"
       done
       if [ "$FOUND" -ne "1" ];then
         echo
         echo "INFO: Regular shutdown not successful,  sending SIGKILL to process"
         invoke_kill
         RET="$?"
       fi
    elif [ -f "$ACTIVEMQ_PIDFILE" ];then
       echo "ERROR: No or outdated process id in '$ACTIVEMQ_PIDFILE'"
       echo
       echo "INFO: Removing $ACTIVEMQ_PIDFILE"
    else
       echo "ActiveMQ not running"
       exit 0
    fi
    rm -f "$ACTIVEMQ_PIDFILE" >/dev/null 2>&1
    rm -f "$ACTIVEMQ_DATA/stop.pid" >/dev/null 2>&1
    exit $RET
}

 

3.15 功能 : 在一个运行中的ActiveMQ实例上调用一个任务

 

3.15.1 函数 : invoke_task()

在一个运行的AMQ实例上调用一个任务

$1    :   "checkforrunning",如果activemq没有运行则不调用任务,否则要调用任务。

@RET   :  0 => 成功

                 !1 => 错误

注意 : 本函数使用了全局定义的变量

- $ACTIVEMQ_QUEUEMANAGERURL      : 队列管理器的url

- $ACTIVEMQ_OPTS                                  : 附加选项

- $ACTIVEMQ_SUNJMX_START                : JMX设定的选项

- $ACTIVEMQ_SSL_OPTS                          : SSL加密相关的选项

在函数invoke_task里

定义一个局部变量CHECKRUNNING来保存传递给本函数的第一个参数。

在opts后追加ssl的opts。

如果CHECKRUNNING等于"checkforrunning",则

        如果 checkRunning不为真,则

                打印  “AMQ没有运行”并退出函数。

再如果 CHECKRUNNING 等于 "checkfornotrunning" ,则

        如果 checkRunning 为真,则

                打印 “AMQ 正在运行” 并 退出函数。

调用所有java二进制程序中的任务。

如果参数 $1 等于 "browse" 或  $ACTIVEMQ_QUEUEMANAGERURL 不为空,则

        将 $COMMANDLINE_ARGS 里以browse开头的字段删除,同变量$ACTIVEMQ_QUEUEMANAGERURL 一起赋值给变量 COMMANDLINE_ARGS ;

再如果 $1 等于 "query" 或 $ACTIVEMQ_QUEUEMANAGERURL 不为空,则

        将 $COMMANDLINE_ARGS 里以query开头的字段删除,同变量 $ACTIVEMQ_SUNJMX_CONTROL一起赋值给变量 COMMANDLINE_ARGS  ;

否则

        $ACTIVEMQ_SUNJMX_CONTROL 直接追加到  $COMMANDLINE_ARGS。

执行函数invokeJar,并用"$ACTIVEMQ_PIDFILE"作为参数。

实用变量RET记录上面函数的退出状态,并最为本函数的退出状态。

# Invoke a task on a running ActiveMQ instance
#
# $1    : "checkforrunning", do not invoke the task if activemq is not
#         active
#         , invoke task always
# @RET  : 0 => successful
#         !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_QUEUEMANAGERURL : The url of the queuemanager
# - $ACTIVEMQ_OPTS            : Additional options
# - $ACTIVEMQ_SUNJMX_START    : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS        : options for SSL encryption
invoke_task(){

    local CHECKRUNNING="$1"
    ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SSL_OPTS"

    if [ "$CHECKRUNNING" = "checkforrunning" ];then
       if ( ! checkRunning );then
         echo "Activemq is not running."
         exit 1
       fi
    elif [ "$CHECKRUNNING" = "checkfornotrunning" ];then
      if ( checkRunning );then
         echo "Activemq is running."
         exit 1
       fi
    fi

    # call task in java binary
    if [ "$1" = "browse" ] && [ -n "$ACTIVEMQ_QUEUEMANAGERURL" ];then
       COMMANDLINE_ARGS="$ACTIVEMQ_QUEUEMANAGERURL `echo $COMMANDLINE_ARGS|sed 's,^browse,,'`"
    elif [ "$1" = "query" ]  && [ -n "$ACTIVEMQ_QUEUEMANAGERURL" ];then
       COMMANDLINE_ARGS="$ACTIVEMQ_SUNJMX_CONTROL `echo $COMMANDLINE_ARGS|sed 's,^query,,'`"
    else
       COMMANDLINE_ARGS="$COMMANDLINE_ARGS $ACTIVEMQ_SUNJMX_CONTROL"
    fi
    invokeJar "$ACTIVEMQ_PIDFILE"
    RET="$?"
    exit $RET
}

 

3.16 函数 : show_help()

脚本的帮助函数

show_help() {
  invokeJar "$ACTIVEMQ_PIDFILE"|sed "s,Usage: Main,Usage: $0,"
  cat << EOF
Tasks provided by the sysv init script:
    kill            - terminate instance in a drastic way by sending SIGKILL
    restart         - stop running instance (if there is one), start new instance
    console         - start broker in foreground, useful for debugging purposes
    status          - check if activemq process is running

Configuration of this script:
    The configuration of this script is read from the following files:
    $ACTIVEMQ_CONFIGS
    This script searches for the files in the listed order and reads the first available file.
    Modify $ACTIVEMQ_BASE/bin/env or create a copy of that file on a suitable location.
    To use additional configurations for running multiple instances on the same operating system
    rename or symlink script to a name matching to activemq-instance-.
    This changes the configuration location to /etc/default/activemq-instance- and
    \$HOME/.activemqrc-instance-.
EOF
  exit 1
}

 

3.17 主逻辑

主逻辑部分,主要是根据输入的脚本参数,调用相应的前面的函数,以完成相关的功能。

# ------------------------------------------------------------------------
# MAIN

# show help
if [ -z "$1" ];then
 show_help
fi

case "$1" in
  status)
    invoke_status
    ;;
  restart)
    if ( checkRunning );then
      $0 stop
      echo
    fi
    $0 start
    $0 status
    ;;
  start)
    invoke_start
    ;;
  console)
    invoke_console
    exit $?
    ;;
  stop)
    invoke_stop
    exit $?
    ;;
  kill)
    invoke_kill
    exit $?
    ;;
  *)
    invoke_task
    exit $?
esac

 

附录

附录1 : source script | . scritpt |  script 三种方式执行shell脚本的区别

前两种方式 :source script 和 . scritpt 执行脚本效果一样,在当前shell里执行后,script里面的变量在当前shell生效,而不会产生子shell,不会只有在子shell中script的变量才有效。

第三种方式:直接运行脚本,则脚本中的变量只在子shell中有效,在当前shell中无效。

详细说明,请参见文章《在Linux中用source,dot(.)和直接用脚本文件名执行shell脚本的区别》。

附录2 : ps -p 的用法

[inteplay@localhost data]$ ps -p 1174
  PID TTY          TIME CMD
[inteplay@localhost data]$ ps -p 11749
  PID TTY          TIME CMD
11749 ?        2-17:37:04 java

-p 用来指定进程pid,如果没有该进程则只显示列头,且通过java运行的进程,CMD似乎都显示的是java。

 

附录3 : activemq启动脚本完整内容

#!/bin/sh

### BEGIN INIT INFO
# Provides:          activemq
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     3 5
# Default-Stop:      0 1 6
# Short-Description: Starts ActiveMQ
# Description:       Starts ActiveMQ Message Broker Server
### END INIT INFO

# ------------------------------------------------------------------------
# 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.
# ------------------------------------------------------------------------
#
# This script controls standalone Apache ActiveMQ service processes.
# To ensure compatibility to macosx and cygwin we do not utilize
# lsb standard infrastructure for controlling daemons like
# "start-stop-daemon".
#
# See also http://activemq.apache.org/activemq-command-line-tools-reference.html
# for additional commandline arguments
#
# System variables for this script, like ACTIVEMQ_OPTS and ACTIVEMQ_OPTS_MEMORY,
# can be configured in 'env' script located in this directory.
#
# For more information on configuring the script, see http://activemq.apache.org/unix-shell-script.html
#
#
# Authors:
# Marc Schoechlin 

# ------------------------------------------------------------------------
# IMPROVED DEBUGGING (execute with bash -x)
# export PS4=' ${BASH_SOURCE}:${LINENO}(${FUNCNAME[0]}) '
#
# Backup invocation parameters
COMMANDLINE_ARGS="$@"
EXEC_OPTION=""

# ------------------------------------------------------------------------
# HELPERS

# a simple helper to get the current user
setCurrentUser(){
   CUSER="`whoami 2>/dev/null`"
   # Solaris hack
   if [ ! $? -eq 0 ]; then
      CUSER="`/usr/ucb/whoami 2>/dev/null`"
   fi
}

# get a canonical path, macosx and slowlaris does not support radlink -f :-)
pathCanonical() {
    local dst="${1}"
    while [ -h "${dst}" ] ; do
        ls=`ls -ld "${dst}"`
        link=`expr "$ls" : '.*-> \(.*\)$'`
        if expr "$link" : '/.*' > /dev/null; then
            dst="$link"
        else
            dst="`dirname "${dst}"`/$link"
        fi
    done
    local bas="`basename "${dst}"`"
    local dir="`dirname "${dst}"`"
    if [ "$bas" != "$dir" ]; then
      dst="`pathCanonical "$dir"`/$bas"
    fi
    echo "${dst}" | sed -e 's#//#/#g' -e 's#/\./#/#g' -e 's#/[^/]*/\.\./#/#g'
}


# a simple helper to get the activemq installation dir
getActiveMQHome(){
  # get the real path to the binary
  local REAL_BIN="`pathCanonical $0`"
  local REAL_DIR="`dirname $REAL_BIN`/../"
  REAL_DIR="`cd $REAL_DIR && pwd -P`"
  if [ -z "$REAL_DIR" ];then
      echo 'ERROR: unable to find real installtion path fo activemq, you have to define ACTIVEMQ_HOME manually in the config' >&2
      exit 1
  fi
  echo "$REAL_DIR/"

}

# Active MQ installation dir
if [ -z "$ACTIVEMQ_HOME" ] ; then
  ACTIVEMQ_HOME="`getActiveMQHome`"
fi

# Active MQ base dir
if [ -z "$ACTIVEMQ_BASE" ] ; then
  ACTIVEMQ_BASE="$ACTIVEMQ_HOME"
fi

# Configure user specified classpath here or externally using this variable
if [ -z "$ACTIVEMQ_USER_CLASSPATH" ] ; then
    ACTIVEMQ_USER_CLASSPATH=""
fi

# ActiveMQ Classpath configuration
ACTIVEMQ_CLASSPATH="$ACTIVEMQ_BASE/../lib/:$ACTIVEMQ_USER_CLASSPATH"

# Active MQ configuration directory
if [ -z "$ACTIVEMQ_CONF" ] ; then

    # For backwards compat with old variables we let ACTIVEMQ_CONFIG_DIR set ACTIVEMQ_CONF
    if [ -z "$ACTIVEMQ_CONFIG_DIR" ] ; then
        ACTIVEMQ_CONF="$ACTIVEMQ_BASE/conf"
    else
        ACTIVEMQ_CONF="$ACTIVEMQ_CONFIG_DIR"
    fi
fi

# Configure a user with non root privileges, if no user is specified do not change user
if [ -z "$ACTIVEMQ_USER" ] ; then
    ACTIVEMQ_USER=""
fi

# Active MQ data directory
if [ -z "$ACTIVEMQ_DATA" ] ; then

    # For backwards compat with old variables we let ACTIVEMQ_DATA_DIR set ACTIVEMQ_DATA
    if [ -z "$ACTIVEMQ_DATA_DIR" ] ; then
        ACTIVEMQ_DATA="$ACTIVEMQ_BASE/data"
    else
        ACTIVEMQ_DATA="$ACTIVEMQ_DATA_DIR"
    fi
fi

if [ -z "$ACTIVEMQ_TMP" ] ; then
  ACTIVEMQ_TMP="$ACTIVEMQ_BASE/tmp"
fi

if [ ! -d "$ACTIVEMQ_DATA" ]; then
   setCurrentUser
   if ( [ -z "$ACTIVEMQ_USER" ] || [ "$ACTIVEMQ_USER" = "$CUSER" ] );then
        mkdir $ACTIVEMQ_DATA
   elif [ "`id -u`" = "0" ];then
      su -c "mkdir $ACTIVEMQ_DATA" - $ACTIVEMQ_USER;
   fi
fi

# Location of the pidfile
if [ -z "$ACTIVEMQ_PIDFILE" ]; then
  ACTIVEMQ_PIDFILE="$ACTIVEMQ_DATA/activemq.pid"
fi


# ------------------------------------------------------------------------
# LOAD CONFIGURATION

# CONFIGURATION
# For using instances
if ( basename $0 | grep "activemq-instance-" > /dev/null);then
  INST="`basename $0|sed 's/^activemq-instance-//;s/\.sh$//'`"
  ACTIVEMQ_CONFIGS="/etc/default/activemq-instance-${INST} $HOME/.activemqrc-instance-${INST}"
  echo "INFO: Using alternative activemq configuration files: $ACTIVEMQ_CONFIGS"
else
  ACTIVEMQ_CONFIGS="/etc/default/activemq $HOME/.activemqrc $ACTIVEMQ_HOME/bin/env"
fi

# load activemq configuration
CONFIG_LOAD="no"
for ACTIVEMQ_CONFIG in $ACTIVEMQ_CONFIGS;do
   if [ -f "$ACTIVEMQ_CONFIG" ] ; then
     ( . $ACTIVEMQ_CONFIG >/dev/null 2>&1 )
     if [ "$?" != "0" ];then
      echo "ERROR: There are syntax errors in '$ACTIVEMQ_CONFIG'"
      exit 1
     else
       echo "INFO: Loading '$ACTIVEMQ_CONFIG'"
       . $ACTIVEMQ_CONFIG
      CONFIG_LOAD="yes"
      break
     fi
   fi
done

# inform user that default configuration is loaded, no suitable configfile found
if [ "$CONFIG_LOAD" != "yes" ];then
      echo "INFO: Using default configuration";
      echo "      Configurations are loaded in the following order: $ACTIVEMQ_CONFIGS"
      echo
fi

if [ -z "$ACTIVEMQ_OPTS" ] ; then
    ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config"
fi




# ------------------------------------------------------------------------
# OS SPECIFIC SUPPORT

OSTYPE="unknown"

case "`uname`" in
  CYGWIN*) OSTYPE="cygwin" ;;
  Darwin*)
           OSTYPE="darwin"
           if [ -z "$JAVA_HOME" ] && [ "$JAVACMD" = "auto" ];then
             JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
           fi
           ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched
if [ "$OSTYPE" = "cygwin" ]; then
  [ -n "$ACTIVEMQ_HOME" ] &&
    ACTIVEMQ_HOME="`cygpath --unix "$ACTIVEMQ_HOME"`"
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`cygpath --unix "$JAVA_HOME"`"
  [ -n "$ACTIVEMQ_CLASSPATH" ] &&
    ACTIVEMQ_CLASSPATH="`cygpath --path --unix "$ACTIVEMQ_CLASSPATH"`"
fi

# Detect the location of the java binary
if [ -z "$JAVACMD" ] || [ "$JAVACMD" = "auto" ] ; then
  if [ -n "$JAVA_HOME"  ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # IBM's JDK on AIX uses strange locations for the executables
      JAVACMD="$JAVA_HOME/jre/sh/java"
    else
      JAVACMD="$JAVA_HOME/bin/java"
    fi
  fi
fi

# Hm, we still do not know the location of the java binary
if [ -z "$JAVACMD" ] || [ "$JAVACMD" = "auto" ] || [ ! -x "$JAVACMD" ] ; then
    JAVACMD=`which java 2> /dev/null `
    if [ -z "$JAVACMD" ] ; then
        JAVACMD=java
    fi
fi
# Stop here if no java installation is defined/found
if [ ! -x "$JAVACMD" ] ; then
  echo "ERROR: Configuration variable JAVA_HOME or JAVACMD is not defined correctly."
  echo "       (JAVA_HOME='$JAVA_HOME', JAVACMD='$JAVACMD')"
  exit 1
fi

echo "INFO: Using java '$JAVACMD'"

if [ -z "$ACTIVEMQ_BASE" ] ; then
  ACTIVEMQ_BASE="$ACTIVEMQ_HOME"
fi

# For Cygwin, switch paths to Windows format before running java if [ "$OSTYPE" = "cygwin" ]; then
if [ "$OSTYPE" = "cygwin" ];then
  ACTIVEMQ_HOME="`cygpath --windows "$ACTIVEMQ_HOME"`"
  ACTIVEMQ_BASE="`cygpath --windows "$ACTIVEMQ_BASE"`"
  ACTIVEMQ_CONF="`cygpath --windows "$ACTIVEMQ_CONF"`"
  ACTIVEMQ_DATA="`cygpath --windows "$ACTIVEMQ_DATA"`"
  ACTIVEMQ_CLASSPATH=`cygpath --path --windows "$ACTIVEMQ_CLASSPATH"`
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`cygpath --windows "$JAVA_HOME"`"
  CYGHOME="`cygpath --windows "$HOME"`"
  ACTIVEMQ_TMP="`cygpath --windows "$ACTIVEMQ_TMP"`"
  if [ -n "$CYGHOME" ]; then
      ACTIVEMQ_CYGWIN="-Dcygwin.user.home=\"$CYGHOME\""
  fi
fi

# Set default classpath
# Add instance conf dir before AMQ install conf dir to pick up instance-specific classpath entries first
ACTIVEMQ_CLASSPATH="${ACTIVEMQ_CONF}:${ACTIVEMQ_CLASSPATH}"

if [ "$OSTYPE" = "cygwin" ];then
  # remove training backslashes to prevent quoting problems
  ACTIVEMQ_CLASSPATH="`echo ${ACTIVEMQ_CLASSPATH}|sed '~s,[\\]*$,,g'`"
  ACTIVEMQ_HOME="`echo ${ACTIVEMQ_HOME}|sed '~s,[\\]*$,,g'`"
  ACTIVEMQ_BASE="`echo ${ACTIVEMQ_BASE}|sed '~s,[\\]*$,,g'`"
  ACTIVEMQ_CONF="`echo ${ACTIVEMQ_CONF}|sed '~s,[\\]*$,,g'`"
  ACTIVEMQ_DATA="`echo ${ACTIVEMQ_DATA}|sed '~s,[\\]*$,,g'`"
fi

# Start the ActiveMQ JAR
#
#
# @ARG1 : the name of the PID-file
#         If specified, this function starts the java process in background as a daemon
#         and stores the pid of the created process in the file.
#         Output on stdout/stderr will be supressed if this parameter is specified
# @RET  : If unless 0 something went wrong
#
# Note: This function uses a lot of globally defined variables
# - if $ACTIVEMQ_USER is set, the function tries starts the java process whith the specified
#   user
invokeJar(){
   PIDFILE="$1"
   TASK_TODO="$2"
   RET="1"

   if [ ! -f "${ACTIVEMQ_HOME}/bin/activemq.jar" ];then
    echo "ERROR: '${ACTIVEMQ_HOME}/bin/activemq.jar' does not exist, define ACTIVEMQ_HOME in the config"
    exit 1
   fi

   setCurrentUser

   if ( [ -z "$ACTIVEMQ_USER" ] || [ "$ACTIVEMQ_USER" = "$CUSER" ] );then
      DOIT_PREFIX="sh -c "
      DOIT_POSTFIX=";"
   elif [ "`id -u`" = "0" ];then
      DOIT_PREFIX="su -s /bin/sh -c "
      DOIT_POSTFIX=" - $ACTIVEMQ_USER"
      echo "INFO: changing to user '$ACTIVEMQ_USER' to invoke java"
   fi

   # Execute java binary
   if [ -n "$TASK_TODO" ] && [ "$TASK_TODO" != "stop" ];then
      if [ -z "$ACTIVEMQ_OUT" ]; then
         ACTIVEMQ_OUT="/dev/null"
      fi
      $EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
              -Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
              -Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
              -Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
              -Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
              -Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
              $ACTIVEMQ_CYGWIN \
              -jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS >> $ACTIVEMQ_OUT 2>&1 &
              RET=\"\$?\"; APID=\"\$!\";
              echo \$APID > "${PIDFILE}";
              echo \"INFO: pidfile created : '${PIDFILE}' (pid '\$APID')\";exit \$RET" $DOIT_POSTFIX
      RET="$?"
   elif [ -n "$TASK_TODO" ] && [ "$TASK_TODO" = "stop" ];then
          SPID="`cat "${PIDFILE}"`"
          $EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
              -Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
              -Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
              -Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
              -Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
              -Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
              $ACTIVEMQ_CYGWIN \
              -jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS --pid $SPID &
              RET=\"\$?\"; APID=\"\$!\";
              echo \$APID > "${PIDFILE}.stop"; exit \$RET" $DOIT_POSTFIX
      RET="$?"
   else
      $EXEC_OPTION $DOIT_PREFIX "\"$JAVACMD\" $ACTIVEMQ_OPTS $ACTIVEMQ_DEBUG_OPTS \
              -Dactivemq.classpath=\"${ACTIVEMQ_CLASSPATH}\" \
              -Dactivemq.home=\"${ACTIVEMQ_HOME}\" \
              -Dactivemq.base=\"${ACTIVEMQ_BASE}\" \
              -Dactivemq.conf=\"${ACTIVEMQ_CONF}\" \
              -Dactivemq.data=\"${ACTIVEMQ_DATA}\" \
              $ACTIVEMQ_CYGWIN \
              -jar \"${ACTIVEMQ_HOME}/bin/activemq.jar\" $COMMANDLINE_ARGS" $DOIT_POSTFIX
      RET="$?"
   fi
   return $RET
}

# Check if ActiveMQ is running
#
# @RET  : 0 => the activemq process is running
#         1 => process id in $ACTIVEMQ_PIDFILE does not exist anymore
#         2 => something is wrong with the pid file
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file


checkRunning(){
    if [ -f "$ACTIVEMQ_PIDFILE" ]; then
       if  [ -z "`cat $ACTIVEMQ_PIDFILE`" ];then
        echo "ERROR: Pidfile '$ACTIVEMQ_PIDFILE' exists but contains no pid"
        return 2
       fi
       ACTIVEMQ_PID="`cat ${ACTIVEMQ_PIDFILE}`"
       RET="`ps -p "${ACTIVEMQ_PID}"|grep java`"
       if [ -n "$RET" ];then
         return 0;
       else
         return 1;
       fi
    else
         return 1;
    fi
}

checkStopRunning(){
    PID_STOP="${ACTIVEMQ_PIDFILE}.stop"
    if [ -f "$PID_STOP" ]; then
       if  [ -z "`cat $PID_STOP`" ];then
        echo "ERROR: Pidfile os stop process '$PID_STOP' exists but contains no pid"
        return 2
       fi
       THEPID=`cat ${PID_STOP}`
       RET=`ps -p $THEPID|grep java`
       if [ -n "$RET" ];then
         return 0;
       else
         return 1;
       fi
    else
         return 1;
    fi
}

# Check if ActiveMQ is running
#
# @RET  : 0 => the activemq process is running
#         1 => the activemq process is not running
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE : the name of the pid file


invoke_status(){
    if ( checkRunning );then
         PID="`cat $ACTIVEMQ_PIDFILE`"
         echo "ActiveMQ is running (pid '$PID')"
         exit 0
    fi
    echo "ActiveMQ not running"
    exit 1
}

# Start ActiveMQ if not already running
#
# @RET  : 0 => is now started, is already started
#         !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE      : the name of the pid file
# - $ACTIVEMQ_OPTS         : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS     : options for SSL encryption

invoke_start(){
    if ( checkRunning );then
      PID="`cat $ACTIVEMQ_PIDFILE`"
      echo "INFO: Process with pid '$PID' is already running"
      exit 0
    fi

    ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SUNJMX_START $ACTIVEMQ_SSL_OPTS -Djava.awt.headless=true -Djava.io.tmpdir=\"${ACTIVEMQ_TMP}\""

    echo "INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details"
    invokeJar "$ACTIVEMQ_PIDFILE" start
    exit "$?"
}

# Start ActiveMQ in foreground (for debugging)
#
# @RET  : 0 => was started
#         1 => was already started
#         !0 => somthing went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE      : the name of the pid file
# - $ACTIVEMQ_OPTS         : Additional options
# - $ACTIVEMQ_SUNJMX_START : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS     : options for SSL encryption

invoke_console(){
    if ( checkRunning );then
      echo "ERROR: ActiveMQ is already running"
      exit 1
    fi

    ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SUNJMX_START $ACTIVEMQ_SSL_OPTS -Djava.awt.headless=true -Djava.io.tmpdir=\"${ACTIVEMQ_TMP}\""

    COMMANDLINE_ARGS="start `echo $COMMANDLINE_ARGS|sed 's,^console,,'`"
    EXEC_OPTION="exec"
    echo "INFO: Starting in foreground, this is just for debugging purposes (stop process by pressing CTRL+C)"
    echo "INFO: Creating pidfile $ACTIVEMQ_PIDFILE"
    echo "$$" > "$ACTIVEMQ_PIDFILE"
    invokeJar "$ACTIVEMQ_PIDFILE"
    RET="$?"
    echo "INFO: removing pidfile $ACTIVEMQ_PIDFILE"
    exit "$RET"
}


# Kill ActiveMQ
# @RET    : 0 => stop was successful
#          !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE         : the name of the pid file


invoke_kill(){
    if ( checkRunning ); then
       ACTIVEMQ_PID="`cat ${ACTIVEMQ_PIDFILE}`"
       echo "INFO: sending SIGKILL to pid '$ACTIVEMQ_PID'"
       kill -KILL $ACTIVEMQ_PID
       RET="$?"
       rm -f "${ACTIVEMQ_PIDFILE}"
       return $RET
    fi
    echo "INFO: not running, nothing to do"
    return 0
}


# Stop ActiveMQ
# @RET    : 0 => stop was successful
#          !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_PIDFILE         : the name of the pid file
# - $ACTIVEMQ_KILL_MAXSECONDS : the number of seconds to wait for termination of broker after sending
#                              shutdown signal by jmx interface

invoke_stop(){
    RET="1"
    if ( checkRunning );then
       ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SSL_OPTS"
       COMMANDLINE_ARGS="$COMMANDLINE_ARGS $ACTIVEMQ_SUNJMX_CONTROL"

       ACTIVEMQ_PID="`cat $ACTIVEMQ_PIDFILE`"

       invokeJar "$ACTIVEMQ_PIDFILE" "stop"
       RET="$?"

       FOUND="0"
       i=0
       echo "INFO: Waiting at least $ACTIVEMQ_KILL_MAXSECONDS seconds for regular process termination of pid '$ACTIVEMQ_PID' : "
       while [ "$i" -le "$ACTIVEMQ_KILL_MAXSECONDS" ]; do
         if [ ! checkStopRunning ];then
            if [ ! checkRunning ]; then
               echo " FINISHED"
               FOUND="1"
            fi
            break
         fi

         if (checkRunning);then
            sleep 1
            printf  "."
         else
            echo " TERMINATED"
            FOUND="1"
            break
         fi
         i="`expr $i + 1`"
       done
       if [ "$FOUND" -ne "1" ];then
         echo
         echo "INFO: Regular shutdown not successful,  sending SIGKILL to process"
         invoke_kill
         RET="$?"
       fi
    elif [ -f "$ACTIVEMQ_PIDFILE" ];then
       echo "ERROR: No or outdated process id in '$ACTIVEMQ_PIDFILE'"
       echo
       echo "INFO: Removing $ACTIVEMQ_PIDFILE"
    else
       echo "ActiveMQ not running"
       exit 0
    fi
    rm -f "$ACTIVEMQ_PIDFILE" >/dev/null 2>&1
    rm -f "$ACTIVEMQ_DATA/stop.pid" >/dev/null 2>&1
    exit $RET
}

# Invoke a task on a running ActiveMQ instance
#
# $1    : "checkforrunning", do not invoke the task if activemq is not
#         active
#         , invoke task always
# @RET  : 0 => successful
#         !0 => something went wrong
#
# Note: This function uses globally defined variables
# - $ACTIVEMQ_QUEUEMANAGERURL : The url of the queuemanager
# - $ACTIVEMQ_OPTS            : Additional options
# - $ACTIVEMQ_SUNJMX_START    : options for JMX settings
# - $ACTIVEMQ_SSL_OPTS        : options for SSL encryption
invoke_task(){

    local CHECKRUNNING="$1"
    ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS $ACTIVEMQ_SSL_OPTS"

    if [ "$CHECKRUNNING" = "checkforrunning" ];then
       if ( ! checkRunning );then
         echo "Activemq is not running."
         exit 1
       fi
    elif [ "$CHECKRUNNING" = "checkfornotrunning" ];then
      if ( checkRunning );then
         echo "Activemq is running."
         exit 1
       fi
    fi

    # call task in java binary
    if [ "$1" = "browse" ] && [ -n "$ACTIVEMQ_QUEUEMANAGERURL" ];then
       COMMANDLINE_ARGS="$ACTIVEMQ_QUEUEMANAGERURL `echo $COMMANDLINE_ARGS|sed 's,^browse,,'`"
    elif [ "$1" = "query" ]  && [ -n "$ACTIVEMQ_QUEUEMANAGERURL" ];then
       COMMANDLINE_ARGS="$ACTIVEMQ_SUNJMX_CONTROL `echo $COMMANDLINE_ARGS|sed 's,^query,,'`"
    else
       COMMANDLINE_ARGS="$COMMANDLINE_ARGS $ACTIVEMQ_SUNJMX_CONTROL"
    fi
    invokeJar "$ACTIVEMQ_PIDFILE"
    RET="$?"
    exit $RET
}

show_help() {
  invokeJar "$ACTIVEMQ_PIDFILE"|sed "s,Usage: Main,Usage: $0,"
  cat << EOF
Tasks provided by the sysv init script:
    kill            - terminate instance in a drastic way by sending SIGKILL
    restart         - stop running instance (if there is one), start new instance
    console         - start broker in foreground, useful for debugging purposes
    status          - check if activemq process is running

Configuration of this script:
    The configuration of this script is read from the following files:
    $ACTIVEMQ_CONFIGS
    This script searches for the files in the listed order and reads the first available file.
    Modify $ACTIVEMQ_BASE/bin/env or create a copy of that file on a suitable location.
    To use additional configurations for running multiple instances on the same operating system
    rename or symlink script to a name matching to activemq-instance-.
    This changes the configuration location to /etc/default/activemq-instance- and
    \$HOME/.activemqrc-instance-.
EOF
  exit 1
}

# ------------------------------------------------------------------------
# MAIN

# show help
if [ -z "$1" ];then
 show_help
fi

case "$1" in
  status)
    invoke_status
    ;;
  restart)
    if ( checkRunning );then
      $0 stop
      echo
    fi
    $0 start
    $0 status
    ;;
  start)
    invoke_start
    ;;
  console)
    invoke_console
    exit $?
    ;;
  stop)
    invoke_stop
    exit $?
    ;;
  kill)
    invoke_kill
    exit $?
    ;;
  *)
    invoke_task
    exit $?
esac

 

你可能感兴趣的:(activemq)