接上一篇文章:我们启动tomcat下的start.sh
文件,shell脚本到底做了什么呢?在上一篇文章最后,start.sh
最终调用了 catalina.sh 脚本(调用命令为:exec /usr/local/apache-tomcat-9.0.21/bin/catalina.sh start "$@"
);那么catalina.sh
具体干了什么呢?
代码块:
# OS specific support. $var _must_ be set to either true or false.
cygwin=false
darwin=false
os400=false
hpux=false
case "`uname`" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
HP-UX*) hpux=true;;
esac
# resolve links - $0 may be a softlink
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
上述这一段代码,设定了一些变量, 并通过case
判断根据服务器操作系统的不同,设置不同的参数值。通过while循环判断,获取catalina.sh的绝对路径(非链接),赋值给PRG
。在服务器上执行uname
为Linux
。比如我的tomcat的catalina.sh的绝对路径为/usr/local/apache-tomcat-9.0.21/bin/catalina.sh
。此时,变量情况为:
cygwin=false
darwin=false
os400=false
hpux=false
PRG=/usr/local/apache-tomcat-9.0.21/bin/catalina.sh
代码块:
# Only set CATALINA_HOME if not already set
[ -z "$CATALINA_HOME" ] && CATALINA_HOME=`cd "$PRGDIR/.." >/dev/null; pwd`
# Copy CATALINA_BASE from CATALINA_HOME if not already set
[ -z "$CATALINA_BASE" ] && CATALINA_BASE="$CATALINA_HOME"
# Ensure that any user defined CLASSPATH variables are not used on startup,
# but allow them to be specified in setenv.sh, in rare case when it is needed.
CLASSPATH=
if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
. "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
. "$CATALINA_HOME/bin/setenv.sh"
fi
上述代码,通过-z
判断变量CATALINA_HOME
与CATALINA_BASE
是否已经设置;若未设置,则设定默认值。默认情况下,bin
目录下默认是没有setenv.sh
文件。所以上述代码执行后,变量变动情况如下:
PRGDIR=/usr/local/apache-tomcat-9.0.21/bin
CATALINA_HOME=/usr/local/apache-tomcat-9.0.21
CATALINA_BASE=/usr/local/apache-tomcat-9.0.21
CLASSPATH=
代码块:
# For Cygwin, ensure paths are in UNIX format before anything is touched
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
# Ensure that neither CATALINA_HOME nor CATALINA_BASE contains a colon
# as this is used as the separator in the classpath and Java provides no
# mechanism for escaping if the same character appears in the path.
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
上述代码,由于$cygwin=false
,跳过if
判断。接下来两个case
通过$CATALINA_HOME与$CATALINA_BASE
的值是否包含:
判断服务器是否设置了环境变量。若系统设置的环境变量,会给出提示,并退出执行脚本。由于服务器没有CATALINA
的环境变量设置,故此时无变量变化。
代码块:
# For OS400
if $os400; then
# Set job priority to standard for interactive (interactive - 6) by using
# the interactive priority - 6, the helper threads that respond to requests
# will be running at the same priority as interactive jobs.
COMMAND='chgjob job('$JOBNAME') runpty(6)'
system $COMMAND
# Enable multi threading
export QIBM_MULTI_THREADED=Y
fi
# Get standard Java environment variables
if $os400; then
# -r will Only work on the os400 if the files are:
# 1. owned by the user
# 2. owned by the PRIMARY group of the user
# this will not work if the user belongs in secondary groups
. "$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
由于$os400=false
,所以第一段if...else...
跳过,第二段if...else...
进入else
。当setclasspath.sh
文件可读时,执行该文件,否则给出提示,并退出脚本。
注:关于setclasspath.sh
到底在干嘛,我们下次再详述。 此时变量无变化。
代码块:
# Add on extra jar files to CLASSPATH
if [ ! -z "$CLASSPATH" ] ; then
CLASSPATH="$CLASSPATH":
fi
CLASSPATH="$CLASSPATH""$CATALINA_HOME"/bin/bootstrap.jar
if [ -z "$CATALINA_OUT" ] ; then
CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
fi
if [ -z "$CATALINA_TMPDIR" ] ; then
# Define the java.io.tmpdir to use for Catalina
CATALINA_TMPDIR="$CATALINA_BASE"/temp
fi
# Add tomcat-juli.jar to classpath
# tomcat-juli.jar can be over-ridden per instance
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
上述代码,对一些变量进行简单的判断,根据情况赋值,此时变量变化情况为:
CLASSPATH= --> /usr/local/apache-tomcat-9.0.21/bin/bootstrap.jar
CATALINA_OUT=/usr/local/apache-tomcat-9.0.21/logs/catalina.out
CATALINA_TMPDIR=/usr/local/apache-tomcat-9.0.21/temp
CLASSPATH=/usr/local/apache-tomcat-9.0.21/bin/bootstrap.jar --> /usr/local/apache-tomcat-9.0.21/bin/bootstrap.jar:/usr/local/apache-tomcat-9.0.21/bin/tomcat-juli.jar
代码块:
# Bugzilla 37848: When no TTY is available, don't output to console
have_tty=0
if [ -t 1 ]; then
have_tty=1
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
JAVA_HOME=`cygpath --absolute --windows "$JAVA_HOME"`
JRE_HOME=`cygpath --absolute --windows "$JRE_HOME"`
CATALINA_HOME=`cygpath --absolute --windows "$CATALINA_HOME"`
CATALINA_BASE=`cygpath --absolute --windows "$CATALINA_BASE"`
CATALINA_TMPDIR=`cygpath --absolute --windows "$CATALINA_TMPDIR"`
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$JAVA_ENDORSED_DIRS" ] && JAVA_ENDORSED_DIRS=`cygpath --path --windows "$JAVA_ENDORSED_DIRS"`
fi
if [ -z "$JSSE_OPTS" ] ; then
JSSE_OPTS="-Djdk.tls.ephemeralDHKeySize=2048"
fi
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"
# 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
if [ -z "$LOGGING_MANAGER" ]; then
LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
fi
# Set UMASK unless it has been overridden
if [ -z "$UMASK" ]; then
UMASK="0027"
fi
umask $UMASK
上述代码, [ -t 1 ]=true, $cygwin=false
,而后是一些变量的判断。此时变量的变化为:
have_tty=1
JSSE_OPTS="-Djdk.tls.ephemeralDHKeySize=2048"
JAVA_OPTS="-Djdk.tls.ephemeralDHKeySize=2048"
JAVA_OPTS="-Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources"
LOGGING_CONFIG="-Djava.util.logging.config.file=/usr/local/apache-tomcat-9.0.21/conf/logging.properties"
LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
UMASK="0027"
代码块:
# Java 9 no longer supports the java.endorsed.dirs
# system property. Only try to use it if
# JAVA_ENDORSED_DIRS was explicitly set
# or CATALINA_HOME/endorsed exists.
ENDORSED_PROP=ignore.endorsed.dirs
if [ -n "$JAVA_ENDORSED_DIRS" ]; then
ENDORSED_PROP=java.endorsed.dirs
fi
if [ -d "$CATALINA_HOME/endorsed" ]; then
ENDORSED_PROP=java.endorsed.dirs
fi
# Make the umask available when using the org.apache.catalina.security.SecurityListener
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask`"
if [ -z "$USE_NOHUP" ]; then
if $hpux; then
USE_NOHUP="true"
else
USE_NOHUP="false"
fi
fi
unset _NOHUP
if [ "$USE_NOHUP" = "true" ]; then
_NOHUP="nohup"
fi
# Add the JAVA 9 specific start-up parameters required by Tomcat
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.base/java.lang=ALL-UNNAMED"
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.base/java.io=ALL-UNNAMED"
JDK_JAVA_OPTIONS="$JDK_JAVA_OPTIONS --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"
export JDK_JAVA_OPTIONS
上述代码,[ -n "$JAVA_ENDORSED_DIRS" ]=falase, [ -d "$CATALINA_HOME/endorsed" ]=false, [ -z "$USE_NOHUP" ]=true,
,此时变量变化如下:
JAVA_OPTS="-Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027"
USE_NOHUP="false"
JDK_JAVA_OPTIONS="--add-opens=java.base/java.lang=ALL-UNNAMED"
JDK_JAVA_OPTIONS="--add-opens=java.base/java.io=ALL-UNNAMED"
JDK_JAVA_OPTIONS="--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"
代码块:
# ----- Execute The Requested Command -----------------------------------------
# Bugzilla 37848: only output this if we have a TTY
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
上述代码没有做什么操作,只是打印了一些信息而已。
调用此脚本的外部参数为start
,故下述只看 [ $1 = start ]
的代码块:
if [ "$1" = "jpda" ] ; then
略
fi
if [ "$1" = "debug" ] ; then
略
elif [ "$1" = "run" ]; then
略
elif [ "$1" = "start" ] ; then
if [ ! -z "$CATALINA_PID" ]; then
if [ -f "$CATALINA_PID" ]; then
if [ -s "$CATALINA_PID" ]; then
echo "Existing PID file found during start."
if [ -r "$CATALINA_PID" ]; then
PID=`cat "$CATALINA_PID"`
ps -p $PID >/dev/null 2>&1
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
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
else
rm -f "$CATALINA_PID" >/dev/null 2>&1
if [ $? != 0 ]; then
if [ ! -w "$CATALINA_PID" ]; then
echo "Unable to remove or write to empty PID file. Start aborted."
exit 1
fi
fi
fi
fi
fi
shift
touch "$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 \
-D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
-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 "&"
else
eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
-classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$@" start \
>> "$CATALINA_OUT" 2>&1 "&"
fi
if [ ! -z "$CATALINA_PID" ]; then
echo $! > "$CATALINA_PID"
fi
echo "Tomcat started."
elif [ "$1" = "stop" ] ; then
略
elif [ "$1" = "configtest" ] ; then
略
elif [ "$1" = "version" ] ; then
略
else
略
fi
上述非start
外部传参的判断条件省略了。[ "$1" = "start" ]=true, [ ! -z "$CATALINA_PID" ]=false
,此时代码走到 shift
这里,由于只有一个外部传参start
,故 [ "$1" = "-security" ]=false
,此时进入 else
分支,执行下述命令:
eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
-D$ENDORSED_PROP="\"$JAVA_ENDORSED_DIRS\"" \
-classpath "\"$CLASSPATH\"" \
-Dcatalina.base="\"$CATALINA_BASE\"" \
-Dcatalina.home="\"$CATALINA_HOME\"" \
-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
org.apache.catalina.startup.Bootstrap "$@" start \
>> "$CATALINA_OUT" 2>&1 "&"
# 注:从setclasspath.sh得变量
# _RUNJAVA=/usr/java/jdk1.8.0_91/bin/java
# _RUNJDB=/usr/java/jdk1.8.0_91/bin/jdb
# 上述命令,将变量替换掉,为:
/usr/java/jdk1.8.0_91/bin/java
-Djava.util.logging.config.file=/usr/local/apache-tomcat-9.0.21/conf/logging.properties\
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 \
-D$ENDORSED_PROP=\
-classpath /usr/local/apache-tomcat-9.0.21/bin/bootstrap.jar:/usr/local/apache-tomcat-9.0.21/bin/tomcat-juli.jar\
-Dcatalina.base=/usr/local/apache-tomcat-9.0.21 \
-Dcatalina.home=/usr/local/apache-tomcat-9.0.21 \
-Djava.io.tmpdir=/usr/local/apache-tomcat-9.0.21/temp \
org.apache.catalina.startup.Bootstrap start \
>> /usr/local/apache-tomcat-9.0.21/logs/catalina.out 2>&1 &
所以tomcat执行start.sh 脚本时,通常情况下 就是上述这么一个命令。你可以直接在命令行执行此命令:
[root@test-cdh conf]# /usr/java/jdk1.8.0_91/bin/java -Djava.util.logging.config.file=/usr/local/apache-tomcat-9.0.21/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -D= -classpath /usr/local/apache-tomcat-9.0.21/bin/bootstrap.jar:/usr/local/apache-tomcat-9.0.21/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/apache-tomcat-9.0.21 -Dcatalina.home=/usr/local/apache-tomcat-9.0.21 -Djava.io.tmpdir=/usr/local/apache-tomcat-9.0.21/temp org.apache.catalina.startup.Bootstrap start >> /usr/local/apache-tomcat-9.0.21/logs/catalina.out 2>&1 &
[1] 49852
现在是不是觉得,写的很复杂的脚本,只是一条有较多java参数的命令而已,是不是顿时豁然开朗。
附:上述有很多判断的语句,有一博文整理了,如下(链接为:https://blog.csdn.net/weixin_30367873/article/details/95135922):
运算符 描述 示例
文件比较运算符
-e filename 如果 filename 存在,则为真 [ -e /var/log/syslog ]
-d filename 如果 filename 为目录,则为真 [ -d /tmp/mydir ]
-f filename 如果 filename 为常规文件,则为真 [ -f /usr/bin/grep ]
-L filename 如果 filename 为符号链接,则为真 [ -L /usr/bin/grep ]
-r filename 如果 filename 可读,则为真 [ -r /var/log/syslog ]
-w filename 如果 filename 可写,则为真 [ -w /var/mytmp.txt ]
-x filename 如果 filename 可执行,则为真 [ -L /usr/bin/grep ]
filename1 -nt filename2 如果 filename1 比 filename2 新,则为真 [ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2 如果 filename1 比 filename2 旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法)
-z string 如果 string 长度为零,则为真 [ -z "$myvar" ]
-n string 如果 string 长度非零,则为真 [ -n "$myvar" ]
string1 = string2 如果 string1 与 string2 相同,则为真 [ "$myvar" = "one two three" ]
string1 != string2 如果 string1 与 string2 不同,则为真 [ "$myvar" != "one two three" ]
算术比较运算符
num1 -eq num2 等于 [ 3 -eq $mynum ]
num1 -ne num2 不等于 [ 3 -ne $mynum ]
num1 -lt num2 小于 [ 3 -lt $mynum ]
num1 -le num2 小于或等于 [ 3 -le $mynum ]
num1 -gt num2 大于 [ 3 -gt $mynum ]
num1 -ge num2 大于或等于 [ 3 -ge $mynum ]