1. #!/bin/sh

  2. # Licensed to the Apache Software Foundation (ASF) under one or more

  3. # contributor license agreements.  See the NOTICE file distributed with

  4. # this work for additional information regarding copyright ownership.

  5. # The ASF licenses this file to You under the Apache License, Version 2.0

  6. # (the "License"); you may not use this file except in compliance with

  7. # the License.  You may obtain a copy of the License at

  8. #

  9. #     http://www.apache.org/licenses/LICENSE-2.0

  10. #

  11. # Unless required by applicable law or agreed to in writing, software

  12. # distributed under the License is distributed on an "AS IS" BASIS,

  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  14. # See the License for the specific language governing permissions and

  15. # limitations under the License.

  16. # -----------------------------------------------------------------------------

  17. # Start/Stop Script for the CATALINA Server

  18. #

  19. # Environment Variable Prerequisites

  20. #

  21. #   CATALINA_HOME   May point at your Catalina "build" directory.

  22. #

  23. #   CATALINA_BASE   (Optional) Base directory for resolving dynamic portions

  24. #                   of a Catalina installation.  If not present, resolves to

  25. #                   the same directory that CATALINA_HOME points to.

  26. #

  27. #   CATALINA_OUT    (Optional) Full path to a file where stdout and stderr

  28. #                   will be redirected.

  29. #                   Default is $CATALINA_BASE/logs/catalina.out

  30. #

  31. #   CATALINA_OPTS   (Optional) Java runtime options used when the "start",

  32. #                   or "run" command is executed.

  33. #

  34. #   CATALINA_TMPDIR (Optional) Directory path location of temporary directory

  35. #                   the JVM should use (java.io.tmpdir).  Defaults to

  36. #                   $CATALINA_BASE/temp.

  37. #

  38. #   JAVA_HOME       Must point at your Java Development Kit installation.

  39. #                   Required to run the with the "debug" argument.

  40. #

  41. #   JRE_HOME        Must point at your Java Development Kit installation.

  42. #                   Defaults to JAVA_HOME if empty.

  43. #

  44. #   JAVA_OPTS       (Optional) Java runtime options used when the "start",

  45. #                   "stop", or "run" command is executed.

  46. #

  47. #   JAVA_ENDORSED_DIRS (Optional) Lists of of colon separated directories

  48. #                   containing some jars in order to allow replacement of APIs

  49. #                   created outside of the JCP (i.e. DOM and SAX from W3C).

  50. #                   It can also be used to update the XML parser implementation.

  51. #                   Defaults to $CATALINA_HOME/endorsed.

  52. #

  53. #   JPDA_TRANSPORT  (Optional) JPDA transport used when the "jpda start"

  54. #                   command is executed. The default is "dt_socket".

  55. #

  56. #   JPDA_ADDRESS    (Optional) Java runtime options used when the "jpda start"

  57. #                   command is executed. The default is 8000.

  58. #

  59. #   JPDA_SUSPEND    (Optional) Java runtime options used when the "jpda start"

  60. #                   command is executed. Specifies whether JVM should suspend

  61. #                   execution immediately after startup. Default is "n".

  62. #

  63. #   JPDA_OPTS       (Optional) Java runtime options used when the "jpda start"

  64. #                   command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,

  65. #                   and JPDA_SUSPEND are ignored. Thus, all required jpda

  66. #                   options MUST be specified. The default is:

  67. #

  68. #                   -agentlib:jdwp=transport=$JPDA_TRANSPORT,

  69. #                       address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND

  70. #

  71. #   CATALINA_PID    (Optional) Path of the file which should contains the pid

  72. #                   of catalina startup java process, when start (fork) is used

  73. #

  74. #   LOGGING_CONFIG  (Optional) Override Tomcat's logging config file

  75. #                   Example (all one line)

  76. #                   LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"

  77. #

  78. #   LOGGING_MANAGER (Optional) Override Tomcat's logging manager

  79. #                   Example (all one line)

  80. #                   LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"

  81. #

  82. # $Id: catalina.sh 1146097 2011-07-13 15:25:05Z markt $

  83. # -----------------------------------------------------------------------------

  84. export JRE_HOME=/usr/java/jdk1.6.0_38

  85. export CATALINA_HOME=/home/xrltest1/tomcat

  86. JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xmn768m -XX:PermSize=128m -XX:MaxPermSize=256m -XX:+UseParallelOldGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/xrltest1/tomcat/dumpfile/heap.bin  -Xloggc:/home/xrltest1/tomcat/logs/gc.log"

  87. #作者添加的环境申明,如果一台服务器中有多台tomcat要使用不同版本的JVM,就可以直接这这边添加JRE_HOME,不需要再/etc/profile.d中再配置JRE_HOME环境变量

  88. # OS specific support.  $var _must_ be set to either true or false.

  89. #此处语句判断操作系统,同时对操作系统支持

  90. #os400是 IBM的AIX

  91. #darwin是MacOSX 操作环境的操作系统成份

  92. #Darwin是windows平台上运行的类UNIX模拟环境

  93. cygwin=false

  94. os400=false

  95. darwin=false

  96. case "`uname`" in

  97. CYGWIN*) cygwin=true;;

  98. OS400*) os400=true;;

  99. Darwin*) darwin=true;;

  100. esac

  101. # resolve links - $0 may be a softlink

  102. #此处的RPG抓取的是文件名,因为可能是符号链接,所以下面循环语句的作用就是找到文件真实源路径

  103. PRG="$0"

  104. while [ -h "$PRG" ]; do

  105.  ls=`ls -ld "$PRG"`

  106.  link=`expr "$ls" : '.*-> \(.*\)$'`

  107.  if expr "$link" : '/.*' > /dev/null; then

  108.    PRG="$link"

  109.  else

  110.    PRG=`dirname "$PRG"`/"$link"

  111.  fi

  112. done

  113. #获取脚本目录真实目录地址

  114. # Get standard environment variables

  115. PRGDIR=`dirname "$PRG"`

  116. # Only set CATALINA_HOME if not already set

  117. [ -z "$CATALINA_HOME" ] && CATALINA_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`

  118. # Copy CATALINA_BASE from CATALINA_HOME if not already set

  119. [ -z "$CATALINA_BASE" ] && CATALINA_BASE="$CATALINA_HOME"

  120. #上面两个语句判断变量$CATALINA_HOME和$CATALINA_BASE是否存在,不存在则给予附值

  121. #CATALINA_BASE="$CATALINA_HOME"

  122. # Ensure that any user defined CLASSPATH variables are not used on startup,

  123. # but allow them to be specified in setenv.sh, in rare case when it is needed.

  124. CLASSPATH=

  125. #test –r File 文件存在并且可读

  126. if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then

  127.  . "$CATALINA_BASE/bin/setenv.sh"

  128. elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then

  129.  . "$CATALINA_HOME/bin/setenv.sh"

  130. fi

  131. #默认的tomcat的bin目录下没有这个文件,可以自行编写setenv.sh这个文件设定环境变量

  132. # For Cygwin, ensure paths are in UNIX format before anything is touched

  133. if $cygwin; then

  134.  [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`

  135.  [ -n "$JRE_HOME" ] && JRE_HOME=`cygpath --unix "$JRE_HOME"`

  136.  [ -n "$CATALINA_HOME" ] && CATALINA_HOME=`cygpath --unix "$CATALINA_HOME"`

  137.  [ -n "$CATALINA_BASE" ] && CATALINA_BASE=`cygpath --unix "$CATALINA_BASE"`

  138.  [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"`

  139. fi

  140. # For OS400

  141. if $os400; then

  142.  # Set job priority to standard for interactive (interactive - 6) by using

  143.  # the interactive priority - 6, the helper threads that respond to requests

  144.  # will be running at the same priority as interactive jobs.

  145.  COMMAND='chgjob job('$JOBNAME') runpty(6)'

  146.  system $COMMAND

  147.  # Enable multi threading

  148.  export QIBM_MULTI_THREADED=Y

  149. fi

  150. # Get standard Java environment variables

  151. if $os400; then

  152.  # -r will Only work on the os400 if the files are:

  153.  # 1. owned by the user

  154.  # 2. owned by the PRIMARY group of the user

  155.  # this will not work if the user belongs in secondary groups

  156.  BASEDIR="$CATALINA_HOME"

  157.  . "$CATALINA_HOME"/bin/setclasspath.sh

  158. else

  159.  #这点一定要注意了,本脚本中没有赋值却突然冒出的变量

  160.  #都是在setclasspath.sh这个脚本中执行赋值的。比如$_RUNJAVA

  161.  #作者会在下一篇文章中,分析setclasspath.sh这个脚本

  162.  if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then

  163.    BASEDIR="$CATALINA_HOME"

  164.    . "$CATALINA_HOME"/bin/setclasspath.sh

  165.  else

  166.    echo "Cannot find $CATALINA_HOME/bin/setclasspath.sh"

  167.    echo "This file is needed to run this program"

  168.    exit 1

  169.  fi

  170. fi

  171. #以上是出现在其他操作环境下的脚本的可用性设置,因默认linux系统,上面就不做解读了

  172. if [ -z "$CATALINA_BASE" ] ; then

  173.  CATALINA_BASE="$CATALINA_HOME"

  174. fi

  175. #将变量赋值

  176. # Add tomcat-juli.jar and bootstrap.jar to classpath

  177. # tomcat-juli.jar can be over-ridden per instance

  178. if [ ! -z "$CLASSPATH" ] ; then

  179.  CLASSPATH="$CLASSPATH":

  180. fi

  181. #虽然前面已将做出CATALINA_BASE="$CATALINA_HOME"的语句

  182. #此处还是添加了判断,增强了代码的健壮性

  183. #添加变量$CLASSPATH的值

  184. if [ "$CATALINA_BASE" != "$CATALINA_HOME" ] && [ -r "$CATALINA_BASE/bin/tomcat-juli.jar" ] ; then

  185.  CLASSPATH="$CLASSPATH""$CATALINA_BASE"/bin/tomcat-juli.jar:"$CATALINA_HOME"/bin/bootstrap.jar

  186. else

  187.  CLASSPATH="$CLASSPATH""$CATALINA_HOME"/bin/bootstrap.jar

  188. fi

  189. #确认日志路径$CATALINA_OUT

  190. #这部分主要判断这些变量是否预定义,有就以预定义为主,没有就设置为默认格式

  191. if [ -z "$CATALINA_OUT" ] ; then

  192.  CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out

  193. fi

  194. if [ -z "$CATALINA_TMPDIR" ] ; then

  195.  # Define the java.io.tmpdir to use for Catalina

  196.  CATALINA_TMPDIR="$CATALINA_BASE"/temp

  197. fi

  198. # Bugzilla 37848: When no TTY is available, don't output to console

  199. #获取当前shell运行的终端设备

  200. have_tty=0

  201. if [ "`tty`" != "not a tty" ]; then

  202.    have_tty=1

  203. fi

  204. # For Cygwin, switch paths to Windows format before running java

  205. if $cygwin; then

  206.  JAVA_HOME=`cygpath --absolute --windows "$JAVA_HOME"`

  207.  JRE_HOME=`cygpath --absolute --windows "$JRE_HOME"`

  208.  CATALINA_HOME=`cygpath --absolute --windows "$CATALINA_HOME"`

  209.  CATALINA_BASE=`cygpath --absolute --windows "$CATALINA_BASE"`

  210.  CATALINA_TMPDIR=`cygpath --absolute --windows "$CATALINA_TMPDIR"`

  211.  CLASSPATH=`cygpath --path --windows "$CLASSPATH"`

  212.  JAVA_ENDORSED_DIRS=`cygpath --path --windows "$JAVA_ENDORSED_DIRS"`

  213. fi

  214. # Set juli LogManager config file if it is present and an override has not been issued

  215. #确认$LOGGING_CONFIG变量

  216. if [ -z "$LOGGING_CONFIG" ]; then

  217.  if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then

  218.    LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"

  219.  else

  220.    # Bugzilla 45585

  221.    LOGGING_CONFIG="-Dnop"

  222.  fi

  223. fi

  224. #确认$LOGGING_MANAGER变量

  225. if [ -z "$LOGGING_MANAGER" ]; then

  226.  JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"

  227. else

  228.  JAVA_OPTS="$JAVA_OPTS $LOGGING_MANAGER"

  229. fi

  230. # ----- Execute The Requested Command -----------------------------------------

  231. # Bugzilla 37848: only output this if we have a TTY

  232. #正常情况下have_tty=1

  233. if [ $have_tty -eq 1 ]; then

  234.  echo "Using CATALINA_BASE:   $CATALINA_BASE"

  235.  echo "Using CATALINA_HOME:   $CATALINA_HOME"

  236.  echo "Using CATALINA_TMPDIR: $CATALINA_TMPDIR"

  237.  if [ "$1" = "debug" ] ; then

  238.     echo "Using JAVA_HOME:       $JAVA_HOME"

  239.  else

  240.     echo "Using JRE_HOME:        $JRE_HOME"

  241.  fi

  242.      echo "Using CLASSPATH:       $CLASSPATH"

  243.  #以下这句判断设置的$CATALINA_PID变量如果不存在,则显示"Using CATALINA_PID:    $CATALINA_PID",如果存在则不显示

  244.  if [ ! -z "$CATALINA_PID" ]; then

  245.    echo "Using CATALINA_PID:    $CATALINA_PID"

  246.  fi

  247. fi

  248. #以上就是在启动tomcat是输出的环境变量信息

  249. #

  250. #获取第一次参数,jpda在后面的说明为:jpda start        Start Catalina under JPDA debugger

  251. if [ "$1" = "jpda" ] ; then

  252.  if [ -z "$JPDA_TRANSPORT" ]; then

  253. JPDA_TRANSPORT="dt_socket"

  254.  fi

  255.  if [ -z "$JPDA_ADDRESS" ]; then

  256. JPDA_ADDRESS="8000"

  257.  fi

  258.  if [ -z "$JPDA_SUSPEND" ]; then

  259. JPDA_SUSPEND="n"

  260.  fi

  261.  if [ -z "$JPDA_OPTS" ]; then

  262. JPDA_OPTS="-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND"

  263.  fi

  264.  CATALINA_OPTS="$CATALINA_OPTS $JPDA_OPTS"

  265.  shift

  266. fi

  267. #JPDA 模式是开启远程debug模式,端口就是JPDA_ADDRESS,生产环境用不到,不去深入

  268. #这个是debug模式

  269. #值得注意的是变量$_RUNJDB,居然在全文没有找到赋值的语句。

  270. #从这边开始就注意了,里面的if-fi判断很多,一定要先调好格式再看

  271. if [ "$1" = "debug" ] ; then

  272. if $os400; then

  273. echo "Debug command not available on OS400"

  274. exit 1

  275. else

  276. shift

  277. if [ "$1" = "-security" ] ; then

  278.  if [ $have_tty -eq 1 ]; then

  279. echo "Using Security Manager"

  280.  fi

  281.  shift

  282.  exec "$_RUNJDB" "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \

  283. -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \

  284. -sourcepath "$CATALINA_HOME"/../../java \

  285. -Djava.security.manager \

  286. -Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \

  287. -Dcatalina.base="$CATALINA_BASE" \

  288. -Dcatalina.home="$CATALINA_HOME" \

  289. -Djava.io.tmpdir="$CATALINA_TMPDIR" \

  290. org.apache.catalina.startup.Bootstrap "$@" start

  291. else

  292.  exec "$_RUNJDB" "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \

  293. -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \

  294. -sourcepath "$CATALINA_HOME"/../../java \

  295. -Dcatalina.base="$CATALINA_BASE" \

  296. -Dcatalina.home="$CATALINA_HOME" \

  297. -Djava.io.tmpdir="$CATALINA_TMPDIR" \

  298. org.apache.catalina.startup.Bootstrap "$@" start

  299. fi

  300.    fi

  301.   #上面语句是适配AIX环境的,不做解读

  302.  

  303. #当参数是debug时  

  304. elif [ "$1" = "run" ]; then

  305. shift

  306. #当使用shift命令之后,原来的$2会变成$1,并且原有的$1变得不可用,通过$#命令获得的参数个数也会少1

  307. #这样就可以使用$1获取第二个参数

  308.  if [ "$1" = "-security" ] ; then

  309. if [ $have_tty -eq 1 ]; then

  310.  echo "Using Security Manager"

  311. fi

  312. shift

  313. #作废掉前两个参数

  314. exec "$_RUNJAVA" "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \

  315.  -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \

  316.  -Djava.security.manager \

  317.  -Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \

  318.  -Dcatalina.base="$CATALINA_BASE" \

  319.  -Dcatalina.home="$CATALINA_HOME" \

  320.  -Djava.io.tmpdir="$CATALINA_TMPDIR" \

  321.  org.apache.catalina.startup.Bootstrap "$@" start

  322.  else

  323. exec "$_RUNJAVA" "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \

  324.  -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \

  325.  -Dcatalina.base="$CATALINA_BASE" \

  326.  -Dcatalina.home="$CATALINA_HOME" \

  327.  -Djava.io.tmpdir="$CATALINA_TMPDIR" \

  328.  org.apache.catalina.startup.Bootstrap "$@" start

  329. #这个命令其实就是java命令,指定org.apache.catalina.startup.Bootstrap 这个class文件,$@和"start"作用类似于传参到前面的安格class里

  330.  fi

  331. #正式进入启动的过程啦~

  332. elif [ "$1" = "start" ] ; then

  333.  if [ ! -z "$CATALINA_PID" ]; then

  334.  #test –z 字符串 字符串的长度为零 ,判断这个变量或者文件内有数据

  335. if [ -f "$CATALINA_PID" ]; then

  336. #-f 该『文件名』是否为文件(file)?(常用)

  337.  if [ -s "$CATALINA_PID" ]; then

  338.  #-s 侦测该文件名是否为『非空白文件』?

  339. echo "Existing PID file found during start."

  340. if [ -r "$CATALINA_PID" ]; then

  341. #-r 侦测该文件名是否具有『可读』的属性?

  342. #以上if语句主要判断这个$CATALINA_PID,是否能正常可读

  343.  PID=`cat "$CATALINA_PID"`

  344.  ps -p $PID >/dev/null 2>&1

  345.  if [ $? -eq 0 ] ; then

  346.  #判断这个PID现在有没有被占用,有就输出这个tomcat依旧在运行,退出

  347.  #上面这段语句功能非常好,可以判断出这个PID是否还在运行

  348. echo "Tomcat appears to still be running with PID $PID. Start aborted."

  349. exit 1

  350.  else

  351. echo "Removing/clearing stale PID file."

  352. rm -f "$CATALINA_PID" >/dev/null 2>&1

  353. #删除了这个$CATALINA_PID文件

  354. if [ $? != 0 ]; then

  355.  if [ -w "$CATALINA_PID" ]; then

  356.  #-w 侦测该文件名是否具有『可写』的属性?

  357. cat /dev/null > "$CATALINA_PID"

  358. #清空$CATALINA_PID文件

  359.  else

  360.  #如果不具有可写权限,则输出信息,退出

  361. echo "Unable to remove or clear stale PID file. Start aborted."

  362. exit 1

  363.  fi

  364. fi

  365.  fi

  366. else

  367. #如果"$CATALINA_PID"没有可读权限,任然输出信息退出。

  368.  echo "Unable to read PID file. Start aborted."

  369.  exit 1

  370. fi

  371.  else

  372.  #"$CATALINA_PID"是空白文件

  373. rm -f "$CATALINA_PID" >/dev/null 2>&1

  374. #强制删除$CATALINA_PID文件

  375. if [ $? != 0 ]; then

  376. #成功则进行判断,没有读权限则退出脚本

  377.  if [ ! -w "$CATALINA_PID" ]; then

  378. echo "Unable to remove or write to empty PID file. Start aborted."

  379. exit 1

  380.  fi

  381. fi

  382.  fi

  383. fi

  384. fi

  385. #这段语句,主要目的就是清空$CATALINA_PID文件,如果出现不可读写,则输出信息退出

  386.  shift

  387.  #作废掉前面参数,$1将表示第二个参数

  388.  touch "$CATALINA_OUT"

  389.  #创建$CATALINA_OUT变量路径文件

  390.  if [ "$1" = "-security" ] ; then

  391.  #如果第二个参数是-security

  392. if [ $have_tty -eq 1 ]; then

  393.  echo "Using Security Manager"

  394. fi

  395. shift

  396. "$_RUNJAVA" "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \

  397.  -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \

  398.  -Djava.security.manager \

  399.  -Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy \

  400.  -Dcatalina.base="$CATALINA_BASE" \

  401.  -Dcatalina.home="$CATALINA_HOME" \

  402.  -Djava.io.tmpdir="$CATALINA_TMPDIR" \

  403.  org.apache.catalina.startup.Bootstrap "$@" start \

  404.  >> "$CATALINA_OUT" 2>&1 &

  405.  else

  406.  #我们平时执行启动tomcat核心就是这一句了

  407.  #

  408. "$_RUNJAVA" "$LOGGING_CONFIG" $JAVA_OPTS $CATALINA_OPTS \

  409.  -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \

  410.  -Dcatalina.base="$CATALINA_BASE" \

  411.  -Dcatalina.home="$CATALINA_HOME" \

  412.  -Djava.io.tmpdir="$CATALINA_TMPDIR" \

  413.  org.apache.catalina.startup.Bootstrap "$@" start \

  414.  >> "$CATALINA_OUT" 2>&1 &

  415. #从&可以看出启动的命令在后台启动

  416.  fi

  417. if [ ! -z "$CATALINA_PID" ]; then

  418. #判断CATALINA_PID如果不是空字符,则将Shell最后运行的后台Process的PID 传给$CATALINA_PID

  419. echo $! > "$CATALINA_PID"

  420. #在使用命令运行进程至后台时,可以使用$!抓取前面启动运行在后台进程的进程号

  421. fi

  422. fi

  423. #下面开始了tomcat停止模块了

  424. elif [ "$1" = "stop" ] ; then

  425.  shift

  426.  SLEEP=5

  427.    

  428.  if [ ! -z "$1" ]; then

  429.    echo $1 | grep "[^0-9]" >/dev/null 2>&1

  430.    if [ $? -gt 0 ]; then

  431.      SLEEP=$1

  432.      shift

  433.    fi

  434.  fi

  435.  #上面语句主要是判断停止语句执行到此时,设定几秒后再执行停止语句

  436.  #用来配合stop n

  437.  

  438.  FORCE=0

  439.  if [ "$1" = "-force" ]; then

  440.    shift

  441.    FORCE=1

  442.  fi

  443.  #如果参数中使用了-force,则FORCE=1

  444.  

  445.  if [ ! -z "$CATALINA_PID" ]; then

  446.  #$CATALINA_PID文件不是非空

  447.    if [ -f "$CATALINA_PID" ]; then

  448.      if [ -s "$CATALINA_PID" ]; then

  449.        kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1

  450. #kill -0 pid 不发送任何信号,但是系统会进行错误检查。

  451.        if [ $? -gt 0 ]; then

  452.          echo "PID file found but no matching process was found. Stop aborted."

  453.          exit 1

  454.        fi

  455.      else

  456.        echo "PID file is empty and has been ignored."

  457.      fi

  458.    else

  459.      echo "\$CATALINA_PID was set but the specified file does not exist. Is Tomcat running? Stop aborted."

  460.      exit 1

  461.    fi

  462.  fi

  463.  #以上脚本是进行停止命令检错的,如果可能停止不了,则可以直接报错

  464.  

  465.  "$_RUNJAVA" $JAVA_OPTS \

  466.    -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH" \

  467.    -Dcatalina.base="$CATALINA_BASE" \

  468.    -Dcatalina.home="$CATALINA_HOME" \

  469.    -Djava.io.tmpdir="$CATALINA_TMPDIR" \

  470.    org.apache.catalina.startup.Bootstrap "$@" stop

  471. #这个就是停止脚本的核心命令了

  472.  

  473.  if [ ! -z "$CATALINA_PID" ]; then

  474.    if [ -f "$CATALINA_PID" ]; then

  475.      while [ $SLEEP -ge 0 ]; do

  476.        kill -0 `cat "$CATALINA_PID"` >/dev/null 2>&1

  477.        if [ $? -gt 0 ]; then

  478.          rm -f "$CATALINA_PID" >/dev/null 2>&1

  479.          if [ $? != 0 ]; then

  480.            if [ -w "$CATALINA_PID" ]; then

  481.              cat /dev/null > "$CATALINA_PID"

  482.            else

  483.              echo "Tomcat stopped but the PID file could not be removed or cleared."

  484.            fi

  485.          fi

  486.          break

  487.        fi

  488.        if [ $SLEEP -gt 0 ]; then

  489.          sleep 1

  490.        fi

  491.        if [ $SLEEP -eq 0 ]; then

  492.          if [ $FORCE -eq 0 ]; then

  493.            echo "Tomcat did not stop in time. PID file was not removed."

  494.          fi

  495.        fi

  496.        SLEEP=`expr $SLEEP - 1 `

  497.      done

  498.    fi

  499.  fi

  500.  #上段语句主要是清空$CATALINA_PID

  501.  

  502.  #值得注意的是,生产环境偶尔不加-force选项,tomcat有时无法停止下来

  503.  #如果参数带"-force" ,则强制kill掉tomcat

  504.  if [ $FORCE -eq 1 ]; then

  505.    if [ -z "$CATALINA_PID" ]; then

  506.      echo "Kill failed: \$CATALINA_PID not set"

  507.    else

  508.      if [ -f "$CATALINA_PID" ]; then

  509.        PID=`cat "$CATALINA_PID"`

  510.        echo "Killing Tomcat with the PID: $PID"

  511.        kill -9 $PID

  512. #强制执行的核心命令

  513.        rm -f "$CATALINA_PID" >/dev/null 2>&1

  514.        if [ $? != 0 ]; then

  515.          echo "Tomcat was killed but the PID file could not be removed."

  516.        fi

  517.      fi

  518.    fi

  519.  fi

  520. #查看版本参数

  521. elif [ "$1" = "version" ] ; then

  522.    "$_RUNJAVA"   \

  523.      -classpath "$CATALINA_HOME/lib/catalina.jar" \

  524.      org.apache.catalina.util.ServerInfo

  525. else

  526.  echo "Usage: catalina.sh ( commands ... )"

  527.  echo "commands:"

  528.  if $os400; then

  529.    echo "  debug             Start Catalina in a debugger (not available on OS400)"

  530.    echo "  debug -security   Debug Catalina with a security manager (not available on OS400)"

  531.  else

  532.    echo "  debug             Start Catalina in a debugger"

  533.    echo "  debug -security   Debug Catalina with a security manager"

  534.  fi

  535.  echo "  jpda start        Start Catalina under JPDA debugger"

  536.  echo "  run               Start Catalina in the current window"

  537.  echo "  run -security     Start in the current window with security manager"

  538.  echo "  start             Start Catalina in a separate window"

  539.  echo "  start -security   Start in a separate window with security manager"

  540.  echo "  stop              Stop Catalina, waiting up to 5 seconds for the process to end"

  541.  echo "  stop n            Stop Catalina, waiting up to n seconds for the process to end"

  542.  echo "  stop -force       Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running"

  543.  echo "  stop n -force     Stop Catalina, wait up to n seconds and then use kill -KILL if still running"

  544.  echo "  version           What version of tomcat are you running?"

  545.  echo "Note: Waiting for the process to end and use of the -force option require that \$CATALINA_PID is defined"

  546.  exit 1

  547. fi