如何编写批处理文件


文章目录


前言

在Windows平台上可以通过批处理文件来启动或关闭一些程序。批处理文件的后缀名必须为bat,可以从Windows Explorer中双击一个批处理文件,也可以在DOS控制台中键入批处理文件的名字来调用它。调用批处理文件后,文件中的每一行命令都会解释


一、如何编写批处理文件

本节将对批处理文件进行介绍,当然本节介绍的内容并不能覆盖所有的内容,重点对rem、if、ehco、goto、label等命令进行介绍。

  • rem
    该命令用于注释,解释器不会执行以rem命令开头的行
  • pause
    该命令用于暂停正在执行的批处理文件,并提示用户按某个键,然后程序会继续执行。如下所示
    如何编写批处理文件
  • echo

该命令用于在DOS控制台上显示一段文本。例如,下面的命令会在控制台输出"Hello World",然后暂停程序,之所以暂停程序是为了能够使控制台将输出的文本显示出来。

echo hello world
pause

如果要显示环境变量的值,需要在环境变量的前后添加%,例如,下面的命令将输出myVar的值:

echo %myVar%

如果需要输出操作系统的名字,就可以使用如下的命令

echo %OS%
  • echo off

使用echo off可以防止将批处理文件中的具体命令输出,而只会输出结果,但是echo off命令本身还是会显示出来。
如何编写批处理文件
如何编写批处理文件

  • @echo off

该命令与echo off命令类似,但它会连echo off命令也隐藏起来
如何编写批处理文件

  • set

set命令用来设置用户定义或命名的环境变量,在批处理文件中设置的环境变量是临时存储在内存当中的,在批处理文件执行完成后会销毁。
例如下面的命令创建了一个名为"THE_KING"的环境变量,将其值设置为"Elvis",并输出到控制台上

set THE_KING=Elvis
echo %THE_KING%
pause

如何编写批处理文件

  • label

使用冒号设置一个标签,然后可以将标签传递给goto命令,这样程序就会跳转到标签指定的位置。下面的语句定义了一个名为end的标签。

:end

有关标签的更多例子请参见对goto命令的介绍。

  • goto

goto命令强制批处理文件跳转到指定标签所在的位置继续执行

@echo off
echo start
goto end
echo I can guarantee this line will not be executed
:end
echo End
pause

在第一行上输出了start之后,批处理文件会执行goto命令,跳转到end标签后的语句继续执行。结果是,跳过第3行内容,没有执行它。
如何编写批处理文件

  • if

if用来执行条件测试。有以下3种用法:

  1. 测试变量的值
  2. 测试文件是否存在
  3. 测试错误值

使用下面的命令格式来测试一个变量的值:
if variable == value nextcommand
例如,下面的if语句将会测试变量myVar的值是不是3。如果是,则它在控制台上输出"Corret":

set myVar=3
if %myVar%==3 echo Correct

运行上面的命令时,会对变量myVar的值进行判断,并输出Correct。
如何编写批处理文件
可以使用下面的命令判断格式来测试文件是否存在

if exist d:\data\my.txt echo file exits

如果在d:\data目录下存在my.txt文件,则打印file exists.

  • not
    not关键字用于对一条语句取反,例如下面的命令在变量myVar的值不是3的时候输出"Corret"。如果在d:\data目录下不存在my1.txt文件,则打印"file not exits".
@echo off
set myVar=2
if not %myVar%==3 echo Correct
if not exist d:\data\my1.txt echo file not exits

如何编写批处理文件

  • exist

当测试文件是否存在时,会使用到if语句和exist命令,在前面已经接触过。

  • 接收参数

可以给批处理文件传递参数,并使用%1引用第一个参数,%2引用第二个参数,以此类推。
例如,下面的命令会在控制台输出第一个参数的值

echo %1

如果批处理文件的名字为test.bat,并使用"test Hello"命令来调用它,那么控制台会输出Hello.
下面的批处理文件会对第一个参数的值进行检查,如果第一个参数的值是start,它就会输出"Starting application";如果第一个参数的值是"stop",就输出"Stopping application";否则输出"Invalid parameter";

@echo off
if %1==start goto start

if %1==stop goto stop

goto invalid

:start
echo Starting application
goto end

:stop
echo Stopping application
goto end

:invalid
echo Invalid parameter %1

:end

如何编写批处理文件
若要检查运行批处理文件是否附带参数,可以将"%1"与空字符串进行比较。例如,对于下面的批处理文件,如果运行时没有使用参数,就会在控制台输出"No parameter":

if "%1"=="" echo No parameter

if ""%1""=="""" echo No parameter
  • shift

shift命令用于将参数索引向后移动一位。即将%2的值复制给%1,%3的值复制给%2,以此类推。例如,下面的代码使用一条shift命令:

@echo off
shift
echo %1
echo %2

如果在运行批处理文件时,附加了3个参数a、b、c,那么上面的命令会有如下输出:
b
c
如何编写批处理文件
移动之后,要使用%0来引用第1个参数,而现在最后一个参数则失效了。

  • call

call命令用于调用另一条命令。

  • setLocal

在批处理文件中使用setlocal对环境命令的修改只是在当前批处理脚本中有效。当遇到endLocal命令后,在批处理文件中修改的环境变量的值会恢复成原来的值。

  • start

打开一个新的Windows控制台,并可以为这个新的控制台指定一个名字,例如start “Title”。此外,在"Title"后面,还可以传入一条将要在新的控制台中执行的命令,如下所示

@echo off
start "Title" echo Hello World

二、Tomcat中的批处理文件

catalina.bat批处理文件用来启动和关闭Tomcat,另外两个文件(startup.bat和shutdown.bat)提供了更简单的启动和关闭Tomcat的方法。实际上,startup.bat和shutdown.bat都会调用catalina.bat文件,并传入相应的参数。
在%CATALINA_HOME%/bin目录下,需要以下面的语法格式调用catalina.bat脚本:

catalina

以下为catalina.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/Stop Script for the CATALINA Server
rem
rem Environment Variable Prerequisites
rem
rem   Do not set the variables in this script. Instead put them into a script
rem   setenv.bat in CATALINA_BASE/bin to keep your customizations separate.
rem
rem   WHEN RUNNING TOMCAT AS A WINDOWS SERVICE:
rem   Note that the environment variables that affect the behavior of this
rem   script will have no effect at all on Windows Services. As such, any
rem   local customizations made in a CATALINA_BASE/bin/setenv.bat script
rem   will also have no effect on Tomcat when launched as a Windows Service.
rem   The configuration that controls Windows Services is stored in the Windows
rem   Registry, and is most conveniently maintained using the "tomcatXw.exe"
rem   maintenance utility, where "X" is the major version of Tomcat you are
rem   running.
rem
rem   CATALINA_HOME   May point at your Catalina "build" directory.
rem
rem   CATALINA_BASE   (Optional) Base directory for resolving dynamic portions
rem                   of a Catalina installation.  If not present, resolves to
rem                   the same directory that CATALINA_HOME points to.
rem
rem   CATALINA_OPTS   (Optional) Java runtime options used when the "start",
rem                   "run" or "debug" command is executed.
rem                   Include here and not in JAVA_OPTS all options, that should
rem                   only be used by Tomcat itself, not by the stop process,
rem                   the version command etc.
rem                   Examples are heap size, GC logging, JMX ports etc.
rem
rem   CATALINA_TMPDIR (Optional) Directory path location of temporary directory
rem                   the JVM should use (java.io.tmpdir).  Defaults to
rem                   %CATALINA_BASE%\temp.
rem
rem   JAVA_HOME       Must point at your Java Development Kit installation.
rem                   Required to run the with the "debug" argument.
rem
rem   JRE_HOME        Must point at your Java Runtime installation.
rem                   Defaults to JAVA_HOME if empty. If JRE_HOME and JAVA_HOME
rem                   are both set, JRE_HOME is used.
rem
rem   JAVA_OPTS       (Optional) Java runtime options used when any command
rem                   is executed.
rem                   Include here and not in CATALINA_OPTS all options, that
rem                   should be used by Tomcat and also by the stop process,
rem                   the version command etc.
rem                   Most options should go into CATALINA_OPTS.
rem
rem   JPDA_TRANSPORT  (Optional) JPDA transport used when the "jpda start"
rem                   command is executed. The default is "dt_socket".
rem
rem   JPDA_ADDRESS    (Optional) Java runtime options used when the "jpda start"
rem                   command is executed. The default is localhost:8000.
rem
rem   JPDA_SUSPEND    (Optional) Java runtime options used when the "jpda start"
rem                   command is executed. Specifies whether JVM should suspend
rem                   execution immediately after startup. Default is "n".
rem
rem   JPDA_OPTS       (Optional) Java runtime options used when the "jpda start"
rem                   command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
rem                   and JPDA_SUSPEND are ignored. Thus, all required jpda
rem                   options MUST be specified. The default is:
rem
rem                   -agentlib:jdwp=transport=%JPDA_TRANSPORT%,
rem                       address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%
rem
rem   JSSE_OPTS       (Optional) Java runtime options used to control the TLS
rem                   implementation when JSSE is used. Default is:
rem                   "-Djdk.tls.ephemeralDHKeySize=2048"
rem
rem   LOGGING_CONFIG  (Optional) Override Tomcat's logging config file
rem                   Example (all one line)
rem                   set LOGGING_CONFIG="-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties"
rem
rem   LOGGING_MANAGER (Optional) Override Tomcat's logging manager
rem                   Example (all one line)
rem                   set LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
rem
rem   TITLE           (Optional) Specify the title of Tomcat window. The default
rem                   TITLE is Tomcat if it's not specified.
rem                   Example (all one line)
rem                   set TITLE=Tomcat.Cluster#1.Server#1 [%DATE% %TIME%]
rem ---------------------------------------------------------------------------

rem 在批处理文件中使用setlocal对环境变量的修改只在当前批处理脚本中有效。当遇到endlocal命令后,在批处理文件的末尾修改的环境变量的值会恢复成原来的值
setlocal

rem Suppress Terminate batch job on CTRL+C
if not ""%1"" == ""run"" goto mainEntry
if "%TEMP%" == "" goto mainEntry
if exist "%TEMP%\%~nx0.run" goto mainEntry
echo Y>"%TEMP%\%~nx0.run"
if not exist "%TEMP%\%~nx0.run" goto mainEntry
echo Y>"%TEMP%\%~nx0.Y"
call "%~f0" %* <"%TEMP%\%~nx0.Y"
rem Use provided errorlevel
set RETVAL=%ERRORLEVEL%
del /Q "%TEMP%\%~nx0.Y" >NUL 2>&1
exit /B %RETVAL%
:mainEntry
del /Q "%TEMP%\%~nx0.run" >NUL 2>&1

rem Guess CATALINA_HOME if not defined
rem 获取当前目录
set "CURRENT_DIR=%cd%"
if not "%CATALINA_HOME%" == "" goto gotHome
set "CATALINA_HOME=%CURRENT_DIR%"
rem 假设当前目录是CATALINA_HOME,如果当前目录下存在bin目录而且目录下存在catalina.bat文件的话,那么猜测是正确的
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
rem 如果不存在对应文件 那么猜测是错误 进入上一个目录 重新设置
cd ..
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
:gotHome

if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
rem 如果猜测都失败了 输出错误消息 告诉用户CATALINA_HOME变量设置错误并调转到end标签所在的位置
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome

rem Copy CATALINA_BASE from CATALINA_HOME if not defined
if not "%CATALINA_BASE%" == "" goto gotBase
set "CATALINA_BASE=%CATALINA_HOME%"
:gotBase

rem Ensure that neither CATALINA_HOME nor CATALINA_BASE contains a semi-colon
rem as this is used as the separator in the classpath and Java provides no
rem mechanism for escaping if the same character appears in the path. Check this
rem by replacing all occurrences of ';' with '' and checking that neither
rem CATALINA_HOME nor CATALINA_BASE have changed
if "%CATALINA_HOME%" == "%CATALINA_HOME:;=%" goto homeNoSemicolon
echo Using CATALINA_HOME:   "%CATALINA_HOME%"
echo Unable to start as CATALINA_HOME contains a semicolon (;) character
goto end
:homeNoSemicolon

if "%CATALINA_BASE%" == "%CATALINA_BASE:;=%" goto baseNoSemicolon
echo Using CATALINA_BASE:   "%CATALINA_BASE%"
echo Unable to start as CATALINA_BASE contains a semicolon (;) character
goto end
:baseNoSemicolon

rem Ensure that any user defined CLASSPATH variables are not used on startup,
rem but allow them to be specified in setenv.bat, in rare case when it is needed.
set CLASSPATH=

rem Get standard environment variables
if not exist "%CATALINA_BASE%\bin\setenv.bat" goto checkSetenvHome
call "%CATALINA_BASE%\bin\setenv.bat"
goto setenvDone
:checkSetenvHome
if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat"
:setenvDone

rem Get standard Java environment variables
if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath
echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat"
echo This file is needed to run this program
goto end
:okSetclasspath
rem 执行指定的脚本
call "%CATALINA_HOME%\bin\setclasspath.bat" %1
if errorlevel 1 goto end

rem Add on extra jar file to CLASSPATH
rem Note that there are no quotes as we do not want to introduce random
rem quotes into the CLASSPATH
if "%CLASSPATH%" == "" goto emptyClasspath
set "CLASSPATH=%CLASSPATH%;"
:emptyClasspath
set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar"

if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir
set "CATALINA_TMPDIR=%CATALINA_BASE%\temp"
:gotTmpdir

rem Add tomcat-juli.jar to classpath
rem tomcat-juli.jar can be over-ridden per instance
if not exist "%CATALINA_BASE%\bin\tomcat-juli.jar" goto juliClasspathHome
set "CLASSPATH=%CLASSPATH%;%CATALINA_BASE%\bin\tomcat-juli.jar"
goto juliClasspathDone
:juliClasspathHome
set "CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\tomcat-juli.jar"
:juliClasspathDone

if not "%JSSE_OPTS%" == "" goto gotJsseOpts
set JSSE_OPTS="-Djdk.tls.ephemeralDHKeySize=2048"
:gotJsseOpts
set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS%"

rem Register custom URL handlers
rem Do this here so custom URL handles (specifically 'war:...') can be used in the security policy
set "JAVA_OPTS=%JAVA_OPTS% -Djava.protocol.handler.pkgs=org.apache.catalina.webresources"

if not "%LOGGING_CONFIG%" == "" goto noJuliConfig
set LOGGING_CONFIG=-Dnop
if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuliConfig
set LOGGING_CONFIG=-Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties"
:noJuliConfig

if not "%LOGGING_MANAGER%" == "" goto noJuliManager
set LOGGING_MANAGER=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
:noJuliManager

rem Configure JAVA 9 specific start-up parameters
set "JDK_JAVA_OPTIONS=%JDK_JAVA_OPTIONS% --add-opens=java.base/java.lang=ALL-UNNAMED"
set "JDK_JAVA_OPTIONS=%JDK_JAVA_OPTIONS% --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"

rem ----- Execute The Requested Command ---------------------------------------

echo Using CATALINA_BASE:   "%CATALINA_BASE%"
echo Using CATALINA_HOME:   "%CATALINA_HOME%"
echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%"
if ""%1"" == ""debug"" goto use_jdk
echo Using JRE_HOME:        "%JRE_HOME%"
goto java_dir_displayed
:use_jdk
echo Using JAVA_HOME:       "%JAVA_HOME%"
:java_dir_displayed
echo Using CLASSPATH:       "%CLASSPATH%"


rem _RUNJAVA这个变量是在setclasspath.bat脚本中定义的 其实就是执行java.exe程序
set _EXECJAVA=%_RUNJAVA%
set MAINCLASS=org.apache.catalina.startup.Bootstrap
set ACTION=start
set SECURITY_POLICY_FILE=
set DEBUG_OPTS=
set JPDA=

rem 检查传入的第一个参数是否为jpda(Java Platform Debugger Architecture Java平台调试器架构)而使用 如果是的话 则设置变量的值
if not ""%1"" == ""jpda"" goto noJpda
set JPDA=jpda
if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport
set JPDA_TRANSPORT=dt_socket
:gotJpdaTransport
if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress
set JPDA_ADDRESS=localhost:8000
:gotJpdaAddress
if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend
set JPDA_SUSPEND=n
:gotJpdaSuspend
if not "%JPDA_OPTS%" == "" goto gotJpdaOpts
set JPDA_OPTS=-agentlib:jdwp=transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%
:gotJpdaOpts
shift
:noJpda
rem 大多数情况下 不需要使用JPDA,因此第一个参数比如是以下几个值之一:debug、embeded、run、start、stop

if ""%1"" == ""debug"" goto doDebug
if ""%1"" == ""run"" goto doRun
if ""%1"" == ""start"" goto doStart
if ""%1"" == ""stop"" goto doStop
if ""%1"" == ""configtest"" goto doConfigTest
if ""%1"" == ""version"" goto doVersion

rem 如果第1个参数不正确,或者没有使用参数,批处理文件会输出如下使用说明并退出
echo Usage:  catalina ( commands ... )
echo commands:
echo   debug             Start Catalina in a debugger
echo   debug -security   Debug Catalina with a security manager
echo   jpda start        Start Catalina under JPDA debugger
echo   run               Start Catalina in the current window
echo   run -security     Start in the current window with security manager
echo   start             Start Catalina in a separate window
echo   start -security   Start in a separate window with security manager
echo   stop              Stop Catalina
echo   configtest        Run a basic syntax check on server.xml
echo   version           What version of tomcat are you running?
goto end

:doDebug
shift
set _EXECJAVA=%_RUNJDB%
set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\java"
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
goto execCmd

:doRun
shift
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
goto execCmd

:doStart
shift
if "%TITLE%" == "" set TITLE=Tomcat
set _EXECJAVA=start "%TITLE%" %_RUNJAVA%
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
goto execCmd

:doStop
shift
set ACTION=stop
set CATALINA_OPTS=
goto execCmd

:doConfigTest
shift
set ACTION=configtest
set CATALINA_OPTS=
goto execCmd

:doVersion
%_EXECJAVA% -classpath "%CATALINA_HOME%\lib\catalina.jar" org.apache.catalina.util.ServerInfo
goto end


:execCmd
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

rem Execute Java with the applicable properties
if not "%JPDA%" == "" goto doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity
%_EXECJAVA% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doSecurity
%_EXECJAVA% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda
%_EXECJAVA% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %JPDA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end
:doSecurityJpda
%_EXECJAVA% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %JPDA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
goto end

:end


总结

为了让用户使用方便,Tomcat附带了批处理文件和Shell脚本,可以方便地启动或关闭servlet容器。在这些批处理文件和shell脚本的帮助下,用户无须为了执行Bootstrap类而记下java.exe程序的选项。相反,用户只需要运行相应的批处理文件或者shell脚本即可。

上一篇:Tomcat异常: Unable to process Jar entry [module-info.class] from Jar


下一篇:2021/11/27 小测