解析Tomcat的启动脚本--startup.bat
概述
我们通常使用 tomcat 中的 startup.bat 来启动 tomcat. 但是这其中干了一些什么事呢?
大家都知道一个 java 程序需要启动的话, 肯定需要 main 方法, 那么这个 main 方法在哪呢?
tomcat 脚本中又是配置了一些什么参数呢, 什么情况下 tomcat 会启动失败呢?
带着一些列的疑问我们来分析 tomcat 的三个最重要的启动脚本:
- startup.bat
- catalina.bat
- setclasspath.bat
startup.bat 脚本
该脚本主要做了以下几件事:
- 设置 catalina_home 环境变量的值
- 找到 catalina.bat 脚本
- 调用 catalina.bat 脚本, 并把参数传过去
贴出简化版本的 startup.bat 脚本的内容
@echo off rem 执行这个命令之后, 增加或者改动的环境变量只限于匹配到 endlocal 命令或者到达文件末尾. setlocal rem 假设 catalina_home 环境变量没有定义 rem 取当前目录的路径值, 赋给 current_dir 变量, 就是 ./apache-tomcat-x.x.xx/bin set "current_dir=%cd%" rem 如果 catalina_home 变量值不是 "" 的话, 调到 gothome 标签处 if not "%catalina_home%" == "" goto gothome rem 如果 catalina_home 是 "" 的话, 设置 catalina_home 变量值为 当前目录的路径值(./apache-tomcat-x.x.xx/bin) set "catalina_home=%current_dir%" rem 判断当前路径下的是否有 bin\catalina.bat, 也就是 ./apache-tomcat-x.x.xx/bin/bin/catalina.bat rem 如果存在的话, 直接调到 okhome 标签处, 显然是不存在的 if exist "%catalina_home%\bin\catalina.bat" goto okhome rem 不存在的话, catalina_home 取上级目录的值, 也就是(./apache-tomcat-x.x.xx/) cd .. set "catalina_home=%cd%" rem 进入 current_dir(./apache-tomcat-x.x.xx/bin) cd "%current_dir%" :gothome rem 通过上面的设置, catalina_home 的值已经是: ./apache-tomcat-x.x.xx/ rem 所以整理是可以找到 catalina.bat 脚本的, 直接调到 okhome 标签处 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 rem 设置 executable 变量指向为 catalina.bat 脚本 set "executable=%catalina_home%\bin\catalina.bat" rem 检查目标可执行文件(catalina.bat)是否存在, 通常情况下是存在的, 直接调到 okexec 标签处 rem 如果不存在的话, 直接退出. 启动 tomcat 结束 if exist "%executable%" goto okexec echo cannot find "%executable%" echo this file is needed to run this program goto end :okexec rem 获取剩余的没有用 shift 取出来的命令行参数, 并保存它们在 cmd_line_args set cmd_line_args= :setargs rem 如果第一个命令行参数是空的话, 跳到 donesetargs 标签处 rem "%1" : 表示执行命令之后的第一个参数 if ""%1""=="""" goto donesetargs rem 第一个参数不是空的话, 拼接到 cmd_line_args 变量 set cmd_line_args=%cmd_line_args% %1 rem 这个命令可以自行百度 shift goto setargs :donesetargs rem 上面设置了 executable 变量的值是指向了 catalina.bat 脚本, 这个利用 call 命令执行调用, 并把参数传进去 rem 接下来, 咱们看 catalina.bat 脚本的内容 rem 完整的命令: ./apache-tomcat-x.x.xx/bin/catalina.bat start call "%executable%" start %cmd_line_args% :end
要想理解脚本中的一些命令, 首先来了解一下常用的命令(我们用的 window 版的)
- rem : 该命令后的代码不会被执行, 相当于注释
- @echo off : 关闭命令的显示, 如果没有设置, 执行了哪些命令都会显示出来
- echo : 输出后面的内容
- setlocal : 执行这个命令之后, 增加或者改动的环境变量的作用范围只限于匹配到 endlocal 命令或者到达文件末尾.
- set : 设置一个变量
- :xxx : 定义一个标签
- goto : 跳转到制定的标签处
- call : 执行命令
我们来一行行分析 startup.bat 脚本
set "current_dir=%cd%"
%cd% : 表示文件所在的目录的路径
如果我们解压的 tomcat 所在的目录为 d:/apache-tomcat-x.x.x/ . 因为 startup.bat 命令在 bin 目录下, 所以此时 %cd% 表示的目录是 d:/apache-tomcat-x.x.x/bin
if not "%catalina_home%" == "" goto gothome
我们通常情况下不会配置 catalina_home 这个环境变量的, 所以这里不会调到 gothome 标签处.
set "catalina_home=%current_dir%"
直接把当前目录假设为 catalina_home 的值
if exist "%catalina_home%\bin\catalina.bat" goto okhome
然后通过固定的格式来判断一下是否有 catalina.bat 脚本, 当然这里是肯定不会存在的, 因为 catalina_home = d:/apache-tomcat-x.x.x/bin
cd .. set "catalina_home=%cd%"
因为 tomcat 的目录格式是固定的, 所以这里直接进入上级目录(cd ..), 然后设置 catalina_home 的值为上级目录( d:/apache-tomcat-x.x.x ).
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
继续往下看, 这里又一次判断了一下 catalina.bat 在这样的目录结构是是否能找到, 如果我们解压完 tomcat 后, 把 startup.bat 放在非 tomcat 的 bin 目录下之后, 这里是找不到的, 就直接 goto end, 退出 tomcat 的启动.
好了, 这里我们直接调到 okhome 标签处.
:okhome set "executable=%catalina_home%\bin\catalina.bat"
好了, 这里很简单, 设置一个 executable 变量的值指向 catalina.bat 脚本.
if exist "%executable%" goto okexec echo cannot find "%executable%" echo this file is needed to run this program goto end
又一次的检查了一下这个脚本是否存在, 存在的话, 直接调到 okexec 标签处, 可以执行了.
如果没有通过检查的话, 依旧退出启动, 并打印错误信息.
:okexec set cmd_line_args= :setargs if ""%1""=="""" goto donesetargs set cmd_line_args=%cmd_line_args% %1 shift goto setargs
先设置了一个 cmd_line_args 变量, 并且其值暂且为空
这里出现了一个 ""%1""=="""", 拆开看 就是判断 "%1" 是否等于 "". 那么 "%1" 又是什么呢?
这是 window 批处理的一个语法, 表示的是执行命令之后的第一个参数, 对于这里, 我们并没有传递什么参数, 所以这里的 "%1" 是 ""(空).
直接跳转到 donesetargs 标签处.
如果不是空的话, 就拼在后面呗.
这里这个 shift 命令意思就是移除一个参数, 举个例子就知道了:
@echo off echo "%1" shift echo "%1"
建一个 test.bat 批处理程序, 然后把上面代码复制进去, 在 cmd 中执行并给它两个参数
下面是执行结果, 这里大家可以把 @echo off 去掉再执行, 验证一下这个命令的作用
ps d:\> .\test hello world "hello" "world" ps d:\>
这样, 大家应该可以理解了.
继续分析
:donesetargs call "%executable%" start %cmd_line_args% :end
在上面设置了 executable = %catalina_home%\bin\catalina.bat , 所以这里实际上是调用了 catalina.bat 这个脚本, 然后传递一个 start 参数给它.
如果我们在 cmd 中运行 startup.bat 并且后面跟着一些参数的话, 这里也一起传递过去了.
这里实际上就是执行了: %catalina_home%\bin\catalina.bat start
总结
这个脚本还是挺简单的, 目的就是找到 catalina.bat 并调用它.
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,下篇继续介绍tomcat相关知识--《解析tomcat的启动脚本--catalina.bat》,有兴趣的朋友可以看下