欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

解析Tomcat的启动脚本--startup.bat

程序员文章站 2022-04-06 22:37:36
概述 我们通常使用 tomcat 中的 startup.bat 来启动 tomcat. 但是这其中干了一些什么事呢? 大家都知道一个 java 程序需要启动的话...

概述

我们通常使用 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》,有兴趣的朋友可以看下