Batch file 如何在一个.BAT文件中运行多个.BAT文件

Batch file 如何在一个.BAT文件中运行多个.BAT文件,batch-file,cmd,Batch File,Cmd,我试图让我的提交build.bat执行其他.bat文件,作为构建过程的一部分 提交build.bat的内容: "msbuild.bat" "unit-tests.bat" "deploy.bat" 这似乎很简单,但是commit build.bat只执行列表中的第一项(msbuild.bat) 我已经分别运行了每个文件,没有问题。使用: call msbuild.bat call unit-tests.bat call deploy.bat call msbuild.bat call uni

我试图让我的
提交build.bat
执行其他.bat文件,作为构建过程的一部分

提交build.bat的内容:

"msbuild.bat"
"unit-tests.bat"
"deploy.bat"
这似乎很简单,但是
commit build.bat
只执行列表中的第一项(
msbuild.bat

我已经分别运行了每个文件,没有问题。

使用:

call msbuild.bat
call unit-tests.bat
call deploy.bat
call msbuild.bat
call unit-tests.bat
call deploy.bat
不使用调用时,当前批处理文件停止,被调用的批处理文件开始执行。这是一种可以追溯到MS-DOS早期的特殊行为。

试试:


要调用
.bat
文件中的
.bat
文件,请使用

call foo.bat

(是的,这是愚蠢的,如果你可以像从命令提示符下那样用
foo.bat
调用它,那就更有意义了,但是正确的方法是使用
call

看看你的文件名,你有没有考虑过使用像或Ant(Java版本)这样的构建工具。与使用bat文件相比,您将获得更多的控制权。

所有其他答案都是正确的:使用call。例如:

 call "msbuild.bat"
历史

在古老的DOS版本中,不可能递归地执行批处理文件。然后引入call命令,调用另一个cmd shell来执行批处理文件,并在完成时将执行返回给调用cmd shell

显然,在以后的版本中,不再需要其他cmd shell

在早期,许多批处理文件依赖于这样一个事实:调用批处理文件不会返回到调用批处理文件。在没有附加语法的情况下改变这种行为会破坏许多系统,比如批处理菜单系统(使用批处理文件作为菜单结构)

与Microsoft的许多情况一样,向后兼容性是导致这种行为的原因

提示

如果批处理文件的名称中有空格,请在名称周围使用引号:

call "unit tests.bat"
顺便说一句:如果您没有批处理文件的所有名称,也可以使用来执行此操作(它不保证批处理文件调用的顺序正确;它遵循文件系统的顺序):

您也可以在通话后对错误级别做出反应。使用:

exit /B 1   # Or any other integer value in 0..255
返回错误级别。0表示正确执行。在调用批处理文件中,可以使用

if errorlevel neq 0 <batch command>

正如其他人所指出的:看看构建系统以替换批处理文件。

您调用多个批处理是为了编译一个程序。 我想当然地认为,如果发生错误:
1) 批处理中的程序将以错误级别退出
2) 你想知道这件事

for %%b in ("msbuild.bat" "unit-tests.bat" "deploy.bat") do call %%b|| exit /b 1

“| |”测试错误级别是否高于0。这样,所有批处理都会按顺序调用,但在出现任何错误时都会停止,让屏幕保持原样,以便您看到任何错误消息。

如果要打开多个命令提示,则可以使用

start cmd /k
/k
:强制执行

启动多个命令提示的操作如下所示

start cmd /k Call rc_hub.bat 4444

start cmd /k Call rc_grid1.bat 5555

start cmd /k Call rc_grid1.bat 6666

start cmd /k Call rc_grid1.bat 5570.

一次运行多个脚本时,我遇到了相同的问题。我一直让它在第一个脚本中死去,却没有意识到它在第一个脚本中退出

:: OneScriptToRunThemAll.bat
CALL ScriptA.bat
CALL ScriptB.bat
EXIT

:: ScriptA.bat
Do Foo
EXIT
::ScriptB.bat
Do bar
EXIT
我删除了所有11个脚本退出行并重试,所有11个脚本在同一命令窗口中按顺序一次一个运行

:: OneScriptToRunThemAll.bat
CALL ScriptA.bat
CALL ScriptB.bat
EXIT

::ScriptA.bat
Do Foo

::ScriptB.bat
Do bar

如果要同时打开多个批处理文件,可以使用call命令。但是,call命令关闭当前bat文件并转到另一个bat文件。如果要同时打开多个,可以尝试以下方法:

@echo off
start cmd "call ex1.bat&ex2.bat&ex3.bat"
Start msbuild.bat
Goto :1
:1
Start unit-tests.bat
Goto :2
:2
Start deploy.bat

依此类推,或对多个文件重复start
cmd
call
…”。这适用于Windows 7,但我不确定其他系统。

如果我们有两个批处理脚本,aaa.bat和bbb.bat,并像下面这样调用

call aaa.bat
call bbb.bat
在执行脚本时,它将首先调用aaa.bat,等待aaa.bat的线程终止,然后调用bbb.bat

但如果您不想等待aaa.bat终止以调用bbb.bat,请尝试使用以下命令:

如果不起作用,请将
start
替换为
call
或尝试以下操作:

@echo off
start cmd "call ex1.bat&ex2.bat&ex3.bat"
Start msbuild.bat
Goto :1
:1
Start unit-tests.bat
Goto :2
:2
Start deploy.bat

只需使用
call
命令!以下是一个例子:

call msbuild.bat
call unit-tests.bat
call deploy.bat
使用正确的报价(有时可能会很棘手):

第一个参数-标题(本例中为空)
第二个arg-/D指定起始目录,如果需要当前工作目录(如“%~dp0”)
第三个参数-要启动的命令,“cmd.exe”
第4个参数-命令的参数,其中参数的引号加倍(这就是在批处理中转义引号的方式)

并行运行多个批处理文件 这里,三个批处理文件以最小化状态在单独的命令窗口上运行。如果不希望最小化它们,请删除
/min
。另外,如果你以后不需要控制它们,那么你可以去掉标题。因此,一个基本命令是-
start cmd/k call systemLogCollector.bat


如果你想终止他们-

taskkill /FI "WindowTitle eq appLogCollector*" /T /F
taskkill /FI "WindowTitle eq uiLogCollector*" /T /F
taskkill /FI "WindowTitle eq systemLogCollector*" /T /F

我知道我参加聚会有点晚了,但这是另一种方式。也就是说,这个方法应该等到第一个完成,第二个完成,依此类推

start "" /wait cmd.exe /c msbuild.bat
start "" /wait cmd.exe /c unit-tests.bat
start "" /wait cmd.exe /c deploy.bat
使用此方法可能产生的唯一问题是,在生成新的cmd.exe实例时,每个cmd.exe实例中都会保留Errorlevel检查

或者

希望这能有所帮助。

使用“&” 正如您所注意到的,在不调用
的情况下直接执行bat,
START
CMD/C
会导致输入并执行第一个文件,然后在第一个文件完成时停止该过程。尽管您仍然可以使用
,这与直接在控制台中使用
命令1和命令2相同:

(
    first.bat
)&(
    second.bat
)& (
    third.bat
)&(
    echo other commands
)
就机器资源而言,这将是最有效的方法,尽管在最后一个块中,您将无法使用命令行
GOTO
SHIFT
SETLOCAL
。。它的功能与在命令提示符下执行命令几乎相同。你不会的
call msbuild.bat
call unit-tests.bat
call deploy.bat
start "" /D "C:\Program Files\ProgramToLaunch" "cmd.exe" "/c call ""C:\Program Files\ProgramToLaunch\programname.bat"""
start "systemLogCollector" /min cmd /k call systemLogCollector.bat
start "uiLogCollector" /min cmd /k call uiLogCollector.bat
start "appLogCollector" /min cmd /k call appLogCollector.bat
taskkill /FI "WindowTitle eq appLogCollector*" /T /F
taskkill /FI "WindowTitle eq uiLogCollector*" /T /F
taskkill /FI "WindowTitle eq systemLogCollector*" /T /F
start "" /wait cmd.exe /c msbuild.bat
start "" /wait cmd.exe /c unit-tests.bat
start "" /wait cmd.exe /c deploy.bat
start "" /wait call msbuild.bat
start "" /wait call unit-tests.bat
start "" /wait call deploy.bat
(
    first.bat
)&(
    second.bat
)& (
    third.bat
)&(
    echo other commands
)
call first.bat
call second.bat
call third.bat
@echo off
CMD /c first.bat
CMD /C second.bat

::not so different than the above lines.
:: MORE,FINDSTR,FIND command will be able to read the piped data 
:: passed from the left side

break|third.bat
:: will be executed in the same console window and will wait to finish
start "" /b /w cmd /c first.bat 

::will start in a separate console window and WONT wait to be finished
:: the second console window wont close automatically so second.bat might need explicit exit command
start "" second.bat

::Will start it in a separate window ,but will wait to finish
:: closing the second window will cause Y/N prompt
:: in the original window 
start "" /w third.cmd


::will start it in the same console window
:: but wont wait to finish. May lead to a little bit confusing output
start "" /b cmd /c fourth.bat
:: will create a separate process with cmd.exe /c
WMIC process call create "%cd%\first.bat","%cd%"

::you can get the PID and monitoring it with other tools
for /f "tokens=2 delims=;= " %%# in ('WMIC process call create "%cd%\second.bat"^,"%cd%" ^|find "ProcessId"') do (
    set "PID=%%#"
)
echo %PID%
SCHTASKS /create /tn BatRunner /tr "%cd%\first.bat" /sc ONCE /sd 01/01/1910 /st 00:00
SCHTASKS /Run /TN BatRunner
SCHTASKS /Delete /TN BatRunner /F
::if the script is not finished after 15 seconds (i.e. ends with pause) it will be killed
ScriptRunner.exe -appvscript %cd%\first.bat -appvscriptrunnerparameters -wait -timeout=15


::will wait or the first called script before to start the second
:: if any of the scripts exit with errorcode different than 0 will try
:: try to restore the system in the original state
ScriptRunner.exe -appvscript second.cmd arg1 arg2 -appvscriptrunnerparameters -wait -rollbackonerror -appvscript third.bat -appvscriptrunnerparameters -wait -timeout=30 -rollbackonerror
start "msbuild.bat"
start "unit-tests.bat"
start "deploy.bat"