脚本内容:
@echo off echo "%~nx0" echo "%1"
执行结果:
PS D:> .test.bat Hello "test.bat" "Hello" PS D:>
第五行:
echo Y>"%TEMP%%~nx0.run"
这段代码很简单, 就是写入字符 Y 到 %TEMP%catalina.bat.run 文件中.
第六行:
if not exist "%TEMP%%~nx0.run" goto mainEntry
又判断了一下 %TEMP%catalina.bat.run 文件是否存在.
第七行:
echo Y>"%TEMP%%~nx0.Y"
同第五行, 写入 Y 到 %TEMP%catalina.bat.Y . 如果文件不存在, 则新建一个.
第八行:
call "%~f0" %* <"%TEMP%%~nx0.Y"
这一行有点意思. 又出现了两个新的东西:
(因为 markdown 语法限制, 把下面代码写到代码块里)
- "%~f0" : 简单说就是表示当前命令的绝对路径.
- "%*" : 我们知道 %1 表示第一个参数, 依次类推, %2 表示第二个.... 那么 %* 就很好理解了, 代表所有参数.
验证一下
脚本内容:
@echo off echo "%*" echo "%~f0"
执行结果:
PS D:> .test.bat Hello World "Hello World" "D:test.bat" PS D:>
那么后面的 <"%TEMP%%~nx0.Y" 意思就是读取 %TEMP%catalina.bat.Y 文件中的内容.
之后又通过 call 进行调用.
我们自己写一个例子, 在 D 盘建立 test.bat 文件, 再建立 catalina.bat.Y 文件
脚本内容:
call "%~f0" %* < D:/catalina.bat.Y
catalina.bat.Y 文件内容
Y
执行结果:
........ D:>call "D:test.bat" Hello World 0<D:/catalina.bat.Y D:>call "D:test.bat" Hello World 0<D:/catalina.bat.Y D:>call "D:test.bat" Hello World 0<D:/catalina.bat.Y D:>call "D:test.bat" Hello World 0<D:/catalina.bat.Y D:>call "D:test.bat" Hello World 0<D:/catalina.bat.Y D:>call "D:test.bat" Hello World 0<D:/catalina.bat.Y D:>call "D:test.bat" Hello World 0<D:/catalina.bat.Y ****** B A T C H R E C U R S I O N exceeds STACK limits ****** Recursion Count=593, Stack Usage=90 percent ****** B A T C H PROCESSING IS A B O R T E D ******
最上面省略了很多重复代码, 从这里发现它不断地调用自己本身, 直到超出了堆栈的限制才停止.
我们如果加上 @echo off 的话
@echo off call "%~f0" %* < D:/catalina.bat.Y
结果只会出现
D:>.test.bat Hello World ****** B A T C H R E C U R S I O N exceeds STACK limits ****** Recursion Count=593, Stack Usage=90 percent ****** B A T C H PROCESSING IS A B O R T E D ******
我们这里只需要明白这些命令的作用就可以, 稍后我们会总结 Tomcat 执行这些命令的目的.
第十行:
set RETVAL=%ERRORLEVEL%
我们如果了解 Linux 的话都知道, 每个命令的执行都会返回一个执行完成之后的退出码. Linux执行完一条命令之后用 echo $? 来查看上一条命令的退出码. 在 Windows 中也是一样的, 命令执行完之后都有自己的退出码. 这里的 %ERRORLEVEL% 就是取的上面的 call 命令的退出码. 赋值给一个变量 RETVAL









