解释器

#!/bin/sh

为什么用 sh 而不是 bash ?因为它要兼容其他的OS环境。

sh vs bash

协议

使用的是 apache licenses2

环境变量

脚本里也说明了,它建议你不要在该脚本(catalina.sh)中设置环境这些环境变量。

应该将设置环境变量的操作,放在 CATALINA/bin 目录下的 setenv.sh 文件中(如果没有,可以创建一个),这样子可以隔离Tomcat的脚本,与你自定义个性化的脚本。

注意, setenv.sh 里不要设置 CATALINA_HOMECATALINA_BASE 因为 setenv.sh 也是通过它们的环境变量来查找 setenv.sh 的。

CATALINA_HOME

可能是指向你的 Catalina 构建的目录。

在多Tomcat实例时,它表示的是一些 Common 的信息

CATALINA_BASE

可选。

它用于一个 Catalina 实例的动态部分(即这些信息是该实例自身私有的,而 CATALINA_HOME 是所有实例信息仅有的)

如果没有的话,它的值与 CATALINA_HOME 相同

CATALINA_OUT

可选。

stdoutstderr 被重定向到的文件的全路径。

默认为 $CATALINA_BASE/logs/catalina.out

CATALINA_OPTS

可选。

当执行 start, rundebug 命令时,用于 Java 运行时(Java Runtime,即JVM)的选项。

包含在这里而不在 JAVA_OPTS 的所有选项,应该仅仅用于 Tomcat 自身,而不应该用于停止进程(stop process),或 version 命令等。

在这里设置的选项有: heap 大小, GC 日志, JMX

CATALINA_TMPDIR

可选。

目录路径,JVM 用它 (java.io.tmpdir) 作为临时目录的路径。

默认为 $CATALINA_BASE/temp

JAVA_HOME

必须指向你的 JDK 安装目录。

当运行 debug 参数时,它是必须的。

JRE_HOME

必须指向你的 JRE 安装目录。

如果为空的话,则默认与 JAVA_HOME 相同。

注意!! 如果 JRE_HOMEJAVA_HOME 同时设置的话,则会使用 JRE_HOME

JAVA_OPTS

可选。

用于执行任何命令时的 Java 运行时选项。

包含在这里而不在 CATALINA_OPTS 的所有选项,它会被用于 Tomcat ,也被用于停止进程(stop process)、 version 等命令中。

绝大部分的选项,都应该放在 CATALINA_OPTS

JPDA_TRANSPORT

可选。

当执行 jpda start 命令时被使用的 JPDA transport 。

默认为 “dt_socket”

JPDA_ADDRESS

可选。

当执行 jpda start 命令时使用的 Java 运行时选项。

默认为 localhost:8000

JPDA_SUSPEND

可选。

当执行 jpda start 命令时使用的 Java 运行时选项。

用于指示 JVM 在启动之后,是否立即挂起执行。

默认是 “n”

JPDA_OPTS

可选。

当执行 jpda start 命令时使用的 Java 运行时选项。

当使用这个选项时, JDPA_TRANSPORTJPDA_ADDRESSJPDA_SUSPEND 都会被忽略。

因此,所有要求的 jpda 选项,必须要指定。默认为:

-agentlib:jdwp=transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND

JSSE_OPTS

可选。

当 JSSE 启用时,该选项用来控制 Java 运行时的 TLS 的实现。默认为:

"-Djdk.tls.ephemeralDHKeySize=2048"

CATALINA_PID

可选。

包含 catalina 启动 Java 进程的 PID 的文件路径。

LOGGING_CONFIG

可选。

覆盖 Tomcat 的日志配置文件。

例子(所有都在同一行):

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

LOGGING_MANAGER

可选。

覆盖 Tomcat 的日志管理

例子(所有都在同一行):

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

UMASK

可选。

覆盖 Tomcat 默认的 UMASK (0027)

USE_NOHUP

可选。

如果设置为字符串的 “true” ,则 start 命令将会使用 nohup ,这样子 Tomcat 进程将会忽略任何的 hangup 信号了。默认是 “false” ,除了在 HP-UX 上运行(它默认就是 “true” )

判断OS

使用 uname 命令。

解析命令软链接的真实位置 => PRG

PRG="$0"

while [ -h "$PRG" ]; do
  ls=`ls -ld "$PRG"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '/.*' > /dev/null; then
    PRG="$link"
  else
    PRG=`dirname "$PRG"`/"$link"
  fi
done

获取命令所在的目录 => PRGDIR

PRGDIR=`dirname "$PRG"`

设置 CATALINA_HOME

如果环境变量 CATALINA_HOME 还没有设置的话,则设置它为 $PRGDIR/..

因为 PRGDIR 通常是在 CATALINA_HOME/bin 目录下,所以,它要返回上一级目录(..)。

设置 CATALINA_BASE

如果环境变量 CATALINA_BASE 还没有设置的话,则设置它为 CATALINA_HOME

设置 CLASSPATH

首先清空所有用户自定义的 CLASSPATH ,然后加载 setenv.sh (优先从 CATALINA_BASE/bin/setenv.sh 查找,如果有则使用它;否则继续在 CATALINA_HOME/bin/setenv.sh 里查找 ) 里的脚本内容(你也可以将 CLASSPATH 的内容添加到 setenv.sh 里,让 Tomcat 来加载)

对于特殊的 Cygwin 环境,则重新为它设置相应的环境变量.

if $cygwin; then
  [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  [ -n "$JRE_HOME" ] && JRE_HOME=`cygpath --unix "$JRE_HOME"`
  [ -n "$CATALINA_HOME" ] && CATALINA_HOME=`cygpath --unix "$CATALINA_HOME"`
  [ -n "$CATALINA_BASE" ] && CATALINA_BASE=`cygpath --unix "$CATALINA_BASE"`
  [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi

输出 CATALINA_HOMECATALINA_BASE 的信息

case $CATALINA_HOME in
  *:*) echo "Using CATALINA_HOME:   $CATALINA_HOME";
       echo "Unable to start as CATALINA_HOME contains a colon (:) character";
       exit 1;
esac
case $CATALINA_BASE in
  *:*) echo "Using CATALINA_BASE:   $CATALINA_BASE";
       echo "Unable to start as CATALINA_BASE contains a colon (:) character";
       exit 1;
esac

加载 setclasspath.sh

它主要用来确保以及设置 JAVA_HOMEJRE_HOME 的。

以及为不同的命令行参数,来判断使用哪个。(比如使用 debug 选项的话,它要求必须是 JDK)

添加 bootstrap.jar 到 CLASSPATH

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

这个 jar 包是整个 Tomcat 的启动核心

设置默认的 CATALINA_OUTCATALINA_TMPDIR

添加 tomcat-juli.jar 到 CLASSPATH

这个 jar 包是 Tomcat 内部用来处理日志相关的

设置 LOGGING_CONFIG

# Set juli LogManager config file if it is present and an override has not been issued
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
    # Bugzilla 45585
    LOGGING_CONFIG="-Dnop"
  fi
fi

这时的 JAVA_OPTS

JAVA_OPTS="$JAVA_OPTS $JSSE_OPTS"

# Register custom URL handlers
# Do this here so custom URL handles (specifically 'war:...') can be used in the security policy
JAVA_OPTS="$JAVA_OPTS -Djava.protocol.handler.pkgs=org.apache.catalina.webresources"

设置 LOGGING_MANAGER

if [ -z "$LOGGING_MANAGER" ]; then
  LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
fi

命令行参数判断

根据不同的命令行参数来设置不同的环境变量以及它们各自特有的参数。

比如

是否有 tty 是否以 jpda 来启动 是否以 debug 来启动 是否以 run 来启动 是否以 start 来启动 是否是 stop 命令(可以添加 -force)

Tomcat 的用法

注意,等等进程结束并使用 -force 选项的话,前提要求设置了 CATALINA_PID 环境变量

./catalina.sh debug :(要 OS400 中不可用)启动 catalina 的 调试器(类似 GDB 那样)

./catalina.sh debug -security :同上,但带有一个 security manager 来启动调试器

./catalina.sh jpda start :在 JPDA Debugger 下启动 catalina(远程调试)

./catalina.sh run :在当前窗口中启动 catalina

./catalina.sh run -security :在当前窗口中启动带有 security manager 的 catalina

./catalina.sh start :在一个分隔的窗口中启动 catalina

./catalina.sh start -security :在一个分隔的窗口中启动带有 security manager 的 catalina

./catalina.sh stop :停止 catalina ,并为进程等待 5 秒后结束

./catalina.sh stop n :停止 catalina ,并为进程等待 n 秒后结束

./catalina.sh stop -force :停止 catalina ,并为进程等待 5 秒后结束,如果该进程还存活的话,再使用使用 kill -KILL 来终止进程

./catalina.sh stop n -force :停止 catalina ,并为进程等待 n 秒后结束,如果该进程还存活的话,再使用使用 kill -KILL 来终止进程

./catalina.sh configtest :检测 server.xml 是否有错误

./catalina.sh version :检测 tomcat 的版本