if$os400; then eval else if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then# 判断文件catalina.sh是否可执行。其中"$PRGDIR"/"$EXECUTABLE"就相当于字符串拼接,不妨设$PRGDIR为/root/tomcat,那结果就是/root/tomcat/catalina.sh echo"Cannot find $PRGDIR/$EXECUTABLE" echo"The file is absent or does not have execute permission" echo"This file is needed to run this program" exit 1 # 退出并设置退出码为1 fi fi
# 如果JAVA_HOME和JRE_HOME都没有设置 #=================================== if [ -z "$JAVA_HOME" -a -z "$JRE_HOME" ]; then# -a表示and # darwin环境下配置JAVA_HOME #---------------------------- if$darwin; then # 设置JAVA_HOME if [ -x '/usr/libexec/java_home' ] ; then# -x判断文件是否可执行 export JAVA_HOME=`/usr/libexec/java_home` elif [ -d "/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home" ]; then# -d判断文件是否是目录 export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home" fi # 其他环境下配置JRE_HOME #------------------------ else JAVA_PATH=`which java 2>/dev/null` # which表示在PATH变量指定的路径中搜索某个系统命令所在的位置, 2>表示重定向错误信息 if [ "x$JAVA_PATH" != "x" ]; then# 如果JAVA_PATH为空 # JRE_HOME 即为java的前两级目录 JAVA_PATH=`dirname $JAVA_PATH 2>/dev/null` JRE_HOME=`dirname $JAVA_PATH 2>/dev/null` fi if [ "x$JRE_HOME" = "x" ]; then# 如果还是没有找到JRE_HOME if [ -x /usr/bin/java ]; then# 判断/usr/bin下有无java JRE_HOME=/usr fi fi fi # JAVA_HOME 和 JRE_HOME 均未配置的情况下,退出程序 #----------------------------------------------- if [ -z "$JAVA_HOME" -a -z "$JRE_HOME" ]; then echo"Neither the JAVA_HOME nor the JRE_HOME environment variable is defined" echo"At least one of these environment variable is needed to run this program" exit 1 fi fi
# 对于debug模式的情况,必须要使用jdk目录 #===================================== if [ -z "$JAVA_HOME" -a "$1" = "debug" ]; then echo"JAVA_HOME should point to a JDK in order to run in debug mode." exit 1 fi
# 如果JRE_HOME为空,则默认使用JAVA_HOME的值 #========================================= if [ -z "$JRE_HOME" ]; then JRE_HOME="$JAVA_HOME" fi
# 如果是在debug模式下,确保java,jdb和javac都能执行 #=============================================== if [ "$1" = "debug" ] ; then if [ "$os400" = "true" ]; then if [ ! -x "$JAVA_HOME"/bin/java -o ! -x "$JAVA_HOME"/bin/javac ]; then echo"The JAVA_HOME environment variable is not defined correctly" echo"This environment variable is needed to run this program" echo"NB: JAVA_HOME should point to a JDK not a JRE" exit 1 fi else # 确保java, jdb和javac都能执行 #------------------------------ if [ ! -x "$JAVA_HOME"/bin/java -o ! -x "$JAVA_HOME"/bin/jdb -o ! -x "$JAVA_HOME"/bin/javac ]; then echo"The JAVA_HOME environment variable is not defined correctly" echo"This environment variable is needed to run this program" echo"NB: JAVA_HOME should point to a JDK not a JRE" exit 1 fi fi fi
# 设置JAVA和JDB的启动命令 #========================= if [ -z "$_RUNJAVA" ]; then _RUNJAVA="$JRE_HOME"/bin/java fi if [ "$os400" != "true" ]; then if [ -z "$_RUNJDB" ]; then _RUNJDB="$JAVA_HOME"/bin/jdb fi fi
# 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.
# ----------------------------------------------------------------------------- # Control Script for the CATALINA Server # # Environment Variable Prerequisites # # Do not set the variables in this script. Instead put them into a script # setenv.sh in CATALINA_BASE/bin to keep your customizations separate. # # CATALINA_HOME May point at your Catalina "build" directory. # # CATALINA_BASE (Optional) Base directory for resolving dynamic portions # of a Catalina installation. If not present, resolves to # the same directory that CATALINA_HOME points to. # # CATALINA_OUT (Optional) Full path to a file where stdout and stderr # will be redirected. # Default is $CATALINA_BASE/logs/catalina.out # # CATALINA_OPTS (Optional) Java runtime options used when the "start", # "run" or "debug" command is executed. # Include here and not in JAVA_OPTS all options, that should # only be used by Tomcat itself, not by the stop process, # the version command etc. # Examples are heap size, GC logging, JMX ports etc. # # CATALINA_TMPDIR (Optional) Directory path location of temporary directory # the JVM should use (java.io.tmpdir). Defaults to # $CATALINA_BASE/temp. # # JAVA_HOME Must point at your Java Development Kit installation. # Required to run the with the "debug" argument. # # JRE_HOME Must point at your Java Runtime installation. # Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME # are both set, JRE_HOME is used. # # JAVA_OPTS (Optional) Java runtime options used when any command # is executed. # Include here and not in CATALINA_OPTS all options, that # should be used by Tomcat and also by the stop process, # the version command etc. # Most options should go into CATALINA_OPTS. # # JPDA_TRANSPORT (Optional) JPDA transport used when the "jpda start" # command is executed. The default is "dt_socket". # # JPDA_ADDRESS (Optional) Java runtime options used when the "jpda start" # command is executed. The default is localhost:8000. # # JPDA_SUSPEND (Optional) Java runtime options used when the "jpda start" # command is executed. Specifies whether JVM should suspend # execution immediately after startup. Default is "n". # # JPDA_OPTS (Optional) Java runtime options used when the "jpda start" # command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS, # and JPDA_SUSPEND are ignored. Thus, all required jpda # options MUST be specified. The default is: # # -agentlib:jdwp=transport=$JPDA_TRANSPORT, # address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND # # JSSE_OPTS (Optional) Java runtime options used to control the TLS # implementation when JSSE is used. Default is: # "-Djdk.tls.ephemeralDHKeySize=2048" # # CATALINA_PID (Optional) Path of the file which should contains the pid # of the catalina startup java process, when start (fork) is # used # # LOGGING_CONFIG (Optional) Override Tomcat's logging config file # Example (all one line) # LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties" # # LOGGING_MANAGER (Optional) Override Tomcat's logging manager # Example (all one line) # LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" # # UMASK (Optional) Override Tomcat's default UMASK of 0027 # # USE_NOHUP (Optional) If set to the string true the start command will # use nohup so that the Tomcat process will ignore any hangup # signals. Default is "false" unless running on HP-UX in which # case the default is "true" # -----------------------------------------------------------------------------
# 确保CATALINA_HOME和CATALINA_BASE中均不包含冒号 #================================================ case$CATALINA_HOMEin *:*) echo"Using CATALINA_HOME: $CATALINA_HOME"; echo"Unable to start as CATALINA_HOME contains a colon (:) character"; exit 1; esac case$CATALINA_BASEin *:*) echo"Using CATALINA_BASE: $CATALINA_BASE"; echo"Unable to start as CATALINA_BASE contains a colon (:) character"; exit 1; esac
if$os400; then COMMAND='chgjob job('$JOBNAME') runpty(6)' system $COMMAND
export QIBM_MULTI_THREADED=Y fi
# 执行setclasspath.sh #========================= if$os400; then . "$CATALINA_HOME"/bin/setclasspath.sh else if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then . "$CATALINA_HOME"/bin/setclasspath.sh else echo"Cannot find $CATALINA_HOME/bin/setclasspath.sh" echo"This file is needed to run this program" exit 1 fi fi
# 向CLASSPATH中添加bootstrap.jar包 #================================== if [ ! -z "$CLASSPATH" ] ; then CLASSPATH="$CLASSPATH": # 在CLASSPATH后面添加一个冒号 fi CLASSPATH="$CLASSPATH""$CATALINA_HOME"/bin/bootstrap.jar # 向CLASSPATH中添加bootstrap.jar包
# 设置CATALINA_OUT变量 #======================= if [ -z "$CATALINA_OUT" ] ; then CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out fi
# 设置CATALINA_TMPDIR变量 #========================== if [ -z "$CATALINA_TMPDIR" ] ; then CATALINA_TMPDIR="$CATALINA_BASE"/temp fi
# 将tomcat-juli.jar包添加进CLASSPATH中 #====================================== if [ -r "$CATALINA_BASE/bin/tomcat-juli.jar" ] ; then CLASSPATH=$CLASSPATH:$CATALINA_BASE/bin/tomcat-juli.jar else CLASSPATH=$CLASSPATH:$CATALINA_HOME/bin/tomcat-juli.jar fi
# 判断是否存在终端 #================== have_tty=0 if [ "`tty`" != "not a tty" ]; then have_tty=1 fi
# 配置日志文件及管理器 #====================== if [ -z "$LOGGING_CONFIG" ]; then if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties" else LOGGING_CONFIG="-Dnop" fi fi
if [ -z "$LOGGING_MANAGER" ]; then LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" fi
# 若之前没有配置默认权限,则设置文件默认权限为640,目录默认权限为750 #=============================================================== if [ -z "$UMASK" ]; then UMASK="0027" fi umask$UMASK
# 设置是否使用nohup方式 #======================= if [ -z "$USE_NOHUP" ]; then if$hpux; then USE_NOHUP="true" else USE_NOHUP="false" fi fi unset _NOHUP # unset删除变量 if [ "$USE_NOHUP" = "true" ]; then _NOHUP=nohup fi
# 如果有终端,就输出如下提示信息 #============================== if [ $have_tty -eq 1 ]; then echo"Using CATALINA_BASE: $CATALINA_BASE" echo"Using CATALINA_HOME: $CATALINA_HOME" echo"Using CATALINA_TMPDIR: $CATALINA_TMPDIR" if [ "$1" = "debug" ] ; then echo"Using JAVA_HOME: $JAVA_HOME" else echo"Using JRE_HOME: $JRE_HOME" fi echo"Using CLASSPATH: $CLASSPATH" if [ ! -z "$CATALINA_PID" ]; then echo"Using CATALINA_PID: $CATALINA_PID" fi fi
# 如果启动选项的第一个参数为jpda,则进行jpda相应设置,可以自己设置运行参数,也可以使用默认参数 # 使用jpda调试catalina # jpda的方式与start联用,虽然看下文代码部分,好像也可以同时使用jpda debug、jpda run等其他组合,但不知运行结果是否正常 #========================================================================================================= if [ "$1" = "jpda" ] ; then if [ -z "$JPDA_TRANSPORT" ]; then JPDA_TRANSPORT="dt_socket" fi if [ -z "$JPDA_ADDRESS" ]; then JPDA_ADDRESS="localhost:8000" fi if [ -z "$JPDA_SUSPEND" ]; then JPDA_SUSPEND="n" fi if [ -z "$JPDA_OPTS" ]; then JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND" fi CATALINA_OPTS="$JPDA_OPTS$CATALINA_OPTS" shift fi
# 如果启动选项的第一个参数为debug # 在调试器中启动catalina #================================= if [ "$1" = "debug" ] ; then if$os400; then echo"Debug command not available on OS400" exit 1 else shift# 位置参数左移。即原来的$2变为$1,原来的$3变为$2 if [ "$1" = "-security" ] ; then# 使用带有安全管理器的调试 if [ $have_tty -eq 1 ]; then echo"Using Security Manager" fi shift exec"$_RUNJDB""$LOGGING_CONFIG"$LOGGING_MANAGER$JAVA_OPTS$CATALINA_OPTS \ -classpath "$CLASSPATH" \ -sourcepath "$CATALINA_HOME"/../../java \ -Djava.security.manager \ -Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \ -Dcatalina.base="$CATALINA_BASE" \ -Dcatalina.home="$CATALINA_HOME" \ -Djava.io.tmpdir="$CATALINA_TMPDIR" \ org.apache.catalina.startup.Bootstrap "$@" start else exec"$_RUNJDB""$LOGGING_CONFIG"$LOGGING_MANAGER$JAVA_OPTS$CATALINA_OPTS \ -classpath "$CLASSPATH" \ -sourcepath "$CATALINA_HOME"/../../java \ -Dcatalina.base="$CATALINA_BASE" \ -Dcatalina.home="$CATALINA_HOME" \ -Djava.io.tmpdir="$CATALINA_TMPDIR" \ org.apache.catalina.startup.Bootstrap "$@" start fi fi
# 从下文中我们可以知道,其实CATALINA_PID文件中保存的就是CATALINA执行后的进程PID #----------------------------------------------------------------------- if [ ! -z "$CATALINA_PID" ]; then# 如果设置了CATALINA_PID if [ -f "$CATALINA_PID" ]; then# 如果已经存在CATALINA_PID文件了 # 如果CATALINA_PID文件中已经有内容了,则判断是否已经有相应进程正在运行,若没有运行的进程,则尝试删除或清空CATALINA_PID文件 #---------------------------------------------------------------------------------------------------------- if [ -s "$CATALINA_PID" ]; then# 如果CATALINA_PID文件中已经有内容了 echo"Existing PID file found during start." if [ -r "$CATALINA_PID" ]; then PID=`cat "$CATALINA_PID"` ps -p $PID >/dev/null 2>&1 # 如果已经有CATALINA在执行,则启动失败 if [ $? -eq 0 ] ; then echo"Tomcat appears to still be running with PID $PID. Start aborted." echo"If the following process is not a Tomcat process, remove the PID file and try again:" ps -f -p $PID exit 1 # 如果没有CATALINA在执行,那么就尝试删除CATALINA_PID文件或者清空 else echo"Removing/clearing stale PID file." rm -f "$CATALINA_PID" >/dev/null 2>&1 if [ $? != 0 ]; then if [ -w "$CATALINA_PID" ]; then cat /dev/null > "$CATALINA_PID" else echo"Unable to remove or clear stale PID file. Start aborted." exit 1 fi fi fi else echo"Unable to read PID file. Start aborted." exit 1 fi # 如果CATALINA_PID文件为空文件,就尝试删除该文件,若无法删除,则直接尝试向该文件中写入数据 #------------------------------------------------------------------------------ else rm -f "$CATALINA_PID" >/dev/null 2>&1 # 2>&1表示将stderr重定向到stdout if [ $? != 0 ]; then# 已存在的CATALINA_PID不可删除 if [ ! -w "$CATALINA_PID" ]; then# CATALINA_PID不可写 echo"Unable to remove or write to empty PID file. Start aborted." exit 1 fi fi fi fi fi
shift touch "$CATALINA_OUT"# 创建CATALINA_OUT的输出文件 if [ "$1" = "-security" ] ; then if [ $have_tty -eq 1 ]; then echo"Using Security Manager" fi shift eval$_NOHUP"\"$_RUNJAVA\"""\"$LOGGING_CONFIG\""$LOGGING_MANAGER$JAVA_OPTS$CATALINA_OPTS \ -classpath "\"$CLASSPATH\"" \ -Djava.security.manager \ -Djava.security.policy=="\"$CATALINA_BASE/conf/catalina.policy\"" \ -Dcatalina.base="\"$CATALINA_BASE\"" \ -Dcatalina.home="\"$CATALINA_HOME\"" \ -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \ org.apache.catalina.startup.Bootstrap "$@" start \ >> "$CATALINA_OUT" 2>&1 "&"
# 设置休眠时间。若stop后面的一个参数为数字,则设置为休眠时间,否则使用默认的5 SLEEP=5 if [ ! -z "$1" ]; then echo$1 | grep "[^0-9]" >/dev/null 2>&1 # 判断stop后第一个参数中是否存在非数字 if [ $? -gt 0 ]; then# 若只有数字,则将SLEEP设置为该时间 SLEEP=$1 shift fi fi
# 设置force FORCE=0 if [ "$1" = "-force" ]; then shift FORCE=1 fi
if [ ! -z "$CATALINA_PID" ]; then if [ -f "$CATALINA_PID" ]; then if [ -s "$CATALINA_PID" ]; then kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1 # kill -0 表示判断一个进程是否存在 if [ $? -gt 0 ]; then# 返回值大于0,即不存在 echo"PID file found but no matching process was found. Stop aborted." exit 1 fi else echo"PID file is empty and has been ignored." fi else echo"\$CATALINA_PID was set but the specified file does not exist. Is Tomcat running? Stop aborted." exit 1 fi fi
# 若停止失败,则调用kill命令来杀死进程 if [ $? != 0 ]; then if [ ! -z "$CATALINA_PID" ]; then echo"The stop command failed. Attempting to signal the process to stop through OS signal." kill -15 `cat "$CATALINA_PID"` >/dev/null 2>&1 # 使用-15方式结束进程 fi fi
if [ ! -z "$CATALINA_PID" ]; then if [ -f "$CATALINA_PID" ]; then while [ $SLEEP -ge 0 ]; do kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1 # 判断进程是否存在 if [ $? -gt 0 ]; then# 若进行已经不存在了,就删除或清空CATALINA_PID文件 rm -f "$CATALINA_PID" >/dev/null 2>&1 if [ $? != 0 ]; then if [ -w "$CATALINA_PID" ]; then cat /dev/null > "$CATALINA_PID" FORCE=0 # 已经停止的情况下,将FORCE标记置为0 else echo"The PID file could not be removed or cleared." fi fi echo"Tomcat stopped." break fi if [ $SLEEP -gt 0 ]; then# 休眠一秒 sleep 1 fi if [ $SLEEP -eq 0 ]; then# 休眠时间到了 echo"Tomcat did not stop in time." if [ $FORCE -eq 0 ]; then echo"PID file was not removed." fi echo"To aid diagnostics a thread dump has been written to standard out." kill -3 `cat "$CATALINA_PID"` # 使用-3方式结束进程 fi SLEEP=`expr $SLEEP - 1 ` done fi fi
# 如果需要强制结束进程,-force命令需要CATALINA_PID存在 KILL_SLEEP_INTERVAL=5 if [ $FORCE -eq 1 ]; then if [ -z "$CATALINA_PID" ]; then echo"Kill failed: \$CATALINA_PID not set" else if [ -f "$CATALINA_PID" ]; then PID=`cat "$CATALINA_PID"` echo"Killing Tomcat with the PID: $PID" kill -9 $PID# 使用-9方式结束进程 # 等待5秒钟 while [ $KILL_SLEEP_INTERVAL -ge 0 ]; do kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1 if [ $? -gt 0 ]; then rm -f "$CATALINA_PID" >/dev/null 2>&1 if [ $? != 0 ]; then if [ -w "$CATALINA_PID" ]; then cat /dev/null > "$CATALINA_PID" else echo"The PID file could not be removed." fi fi echo"The Tomcat process has been killed." break fi if [ $KILL_SLEEP_INTERVAL -gt 0 ]; then sleep 1 fi KILL_SLEEP_INTERVAL=`expr $KILL_SLEEP_INTERVAL - 1 ` done # 进程关闭失败 if [ $KILL_SLEEP_INTERVAL -lt 0 ]; then echo"Tomcat has not been killed completely yet. The process might be waiting on some system call or might be UNINTERRUPTIBLE." fi fi fi fi
echo"Usage: catalina.sh ( commands ... )" echo"commands:" if$os400; then echo" debug Start Catalina in a debugger (not available on OS400)" echo" debug -security Debug Catalina with a security manager (not available on OS400)" else echo" debug Start Catalina in a debugger" echo" debug -security Debug Catalina with a security manager" fi echo" jpda start Start Catalina under JPDA debugger" echo" run Start Catalina in the current window" echo" run -security Start in the current window with security manager" echo" start Start Catalina in a separate window" echo" start -security Start in a separate window with security manager" echo" stop Stop Catalina, waiting up to 5 seconds for the process to end" echo" stop n Stop Catalina, waiting up to n seconds for the process to end" echo" stop -force Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running" echo" stop n -force Stop Catalina, wait up to n seconds and then use kill -KILL if still running" echo" configtest Run a basic syntax check on server.xml - check exit code for result" echo" version What version of tomcat are you running?" echo"Note: Waiting for the process to end and use of the -force option require that \$CATALINA_PID is defined" exit 1