学习一下tomcat启动脚本到底干了什么,tomcat版本为 apache-tomcat-7.0.105-windows-x64
startup.bat 的内容为
@echo off
rem Licensed to the Apache Software Foundation (ASF) under one or more
rem contributor license agreements. See the NOTICE file distributed with
rem this work for additional information regarding copyright ownership.
rem The ASF licenses this file to You under the Apache License, Version 2.0
rem (the "License"); you may not use this file except in compliance with
rem the License. You may obtain a copy of the License at
rem
rem http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.
rem ---------------------------------------------------------------------------
rem Start script for the CATALINA Server
rem ---------------------------------------------------------------------------
setlocal
rem Guess CATALINA_HOME if not defined
set "CURRENT_DIR=%cd%"
if not "%CATALINA_HOME%" == "" goto gotHome
set "CATALINA_HOME=%CURRENT_DIR%"
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome
set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"
rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find "%EXECUTABLE%"
echo This file is needed to run this program
goto end
:okExec
rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs
call "%EXECUTABLE%" start %CMD_LINE_ARGS%
:end
1、第一行 @echo off
@echo off 表示执行的命令都不打印,只打印命令的结果
先看一个例子,将下面内容保存为 1.bat,并使用cmd运行
c:
dir
得到如下结果:
C:\Users\hao\Desktop\test>1.bat
C:\Users\hao\Desktop\test>c:
C:\Users\hao\Desktop\test>dir
驱动器 C 中的卷没有标签。
卷的序列号是 2C56-AF2F
C:\Users\hao\Desktop\test 的目录
2020/07/19 09:37 <DIR> .
2020/07/19 09:37 <DIR> ..
2020/07/19 09:37 7 1.bat
2020/07/19 09:29 0 1.bat.bak
2 个文件 7 字节
2 个目录 20,554,379,264 可用字节
可以发现,运行1.bat 时,脚本将每个命令语句都打印了出来,如上的 “c:”、“dir”。
将脚本开头增加 “@echo off”,再次运行,
@echo off
c:
dir
运行结果如下:
C:\Users\hao\Desktop\test>1.bat
驱动器 C 中的卷没有标签。
卷的序列号是 2C56-AF2F
C:\Users\hao\Desktop\test 的目录
2020/07/19 09:37 <DIR> .
2020/07/19 09:37 <DIR> ..
2020/07/19 09:48 18 1.bat
2020/07/19 09:45 17 1.bat.bak
2 个文件 35 字节
2 个目录 20,553,256,960 可用字节
发现已经没有命令了,只有运行结果。
2、%% 是做什么
%%是从操作系统的环境变量中读取信息
例如:
在cmd中分别执行下面的命令(输出环境变量中的path字段 和 当前目录)
echo %path%
echo %cd%
结果如下:
C:\Users\hao\Desktop\test>echo %path%
D:\apache-maven-3.6.3\bin;d:\java\\bin;C:\Program Files (x86)\Common Files\Oracl
e\Java\javapath;D:\nmap-7.70;C:\Windows\system32;C:\Windows;C:\Windows\System32\
Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\
C:\Users\hao\Desktop\test>echo %cd%
C:\Users\hao\Desktop\test
3、setlocal 是做什么
微软官方解释的 setlocal,
Starts localization of environment variables in a batch file. Localization continues until a matching endlocal command is encountered or the end of the batch file is reached.
在批处理文件中环境变量的本地化操作。意思就是在setlocal命令执行以后,对于环境变量所做的修改只是对于本批处理文件有影响,这个影响直到对应的endlocal命令,或者批处理文件结尾处时消除。
举个例子,如下脚本,按照官方的说法,在setlocal之后修改的环境变量,不会真正修改系统环境变量,
打开cmd,运行如下脚本,
setlocal
path = "test_path"
echo %path%
endlocal
echo %path%
结果是,
C:\Users\hao\Desktop\test>1.bat
C:\Users\hao\Desktop\test>setlocal
C:\Users\hao\Desktop\test>path = "test_path"
C:\Users\hao\Desktop\test>echo "test_path"
"test_path"
C:\Users\hao\Desktop\test>endlocal
C:\Users\hao\Desktop\test>echo D:\apache-maven-3.6.3\bin;d:\java\\bin;C:\Program
Files (x86)\Common Files\Oracle\Java\javapath;D:\nmap-7.70;C:\Windows\system32;
C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\
D:\apache-maven-3.6.3\bin;d:\java\\bin;C:\Program Files (x86)\Common Files\Oracl
e\Java\javapath;D:\nmap-7.70;C:\Windows\system32;C:\Windows;C:\Windows\System32\
Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\
阅读脚本,
1、设置 CURRENT_DIR 为当前目录("D:\tomcat\bin")
2、判断CATALINA_HOME 是否存在,不存在就新建
如果 CATALINA_HOME 不为空,就跳转到 gotHome;如果不存在 CATALINA_HOME,就设置当前目录为 CATALINA_HOME
if not "%CATALINA_HOME%" == "" goto gotHome
set "CATALINA_HOME=%CURRENT_DIR%"
3、判断配置的 %CATALINA_HOME%\bin\ 中是否有 catalina.bat存在。%CATALINA_HOME%\bin\("D:\tomcat\bin\bin")
如果有,就跳转到 okHome;如果没有,就将CATALINA_HOME 设置为 上级目录(d:\tomcat),
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
4、gotHome ---- 如果catalina.bat存在,就跳转到 okHome
如果catalina.bat存在,就跳转到 okHome;如果不存在,报错,结束脚本
:gotHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
5、okHome
将 EXECUTABLE 设置为 catalina.bat 的路径,
如果 catalina.bat 存在,跳转到 okExec;不存在,报错,结束脚本
:okHome
set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"
rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find "%EXECUTABLE%"
echo This file is needed to run this program
goto end
6、okExec、setArgs、doneSetArgs
:okExec
rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs
call "%EXECUTABLE%" start %CMD_LINE_ARGS%
:end
如果有参数,就执行setArgs设置参数,然后执行doneSetArgs;如果没有参数,就直接执行doneSetArgs,
doneSetArgs,调用catalina.bat脚本,并传入用户写的参数。
总结一下,
判断 CATALINA_HOME 是否存在,存在的话,跳转到gotHome,
gotHome的作用是 判断 catalina.bat 是否存在,存在的话,跳转到 okHome,
okHome的作用是 确定脚本执行路径,并判断是否存在该文件(catalina.bat),如果存在,跳转到 okExec,
okExec的作用是 调用 setArgs,设置启动参数,完成后调用 doneSetArgs,
doneSetArgs的作用是 将参数传递到catalina.bat脚本,并执行
参考: