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


691

我正在尝试让我commit-build.bat执行其他.BAT文件,这是我们构建过程的一部分。

内容commit-build.bat

"msbuild.bat"
"unit-tests.bat"
"deploy.bat"

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

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


4
@sean-您不必安装完整的Cygwin软件包即可使命令行实用程序正常工作。只需将所有cygwin dll从包中取出,将它们放在一个路径目录中,然后将所有工具放在另一个路径目录中,就可以了。
Techie Joe

假定每个文件都是批处理文件,为什么不将它们放在一个大文件中并使用超时功能允许每次启动。
CMS_95

Answers:


1195

采用:

call msbuild.bat
call unit-tests.bat
call deploy.bat

不使用CALL时,当前的批处理文件将停止并且被调用的批处理文件开始执行。这是可以追溯到早期MS-DOS时代的一种特殊行为。


很奇怪,我曾尝试在Windows 7上不使用“通话”功能,但我记得它起作用了,但是在Windows XP上却需要此命令。可以吗
Android开发人员

7
在没有调用的情况下,按照原始的DOS规范,应该执行命令链接并且不返回。在添加“ CALL”之前的一个流行选择是打开一个子命令提示符,例如“ command / c second.bat”,因为它也会返回。
Brian Knoblauch

1
我在Windows 7企业版上遇到了问题,所以不仅是xp
Rafiki

5
在Windows 10上,仅执行第一行。然而,farheen的答案奏效了。
robro

2
如何将参数传递给批处理文件,参数之一是带空格的路径。
宙斯

178

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

 call "msbuild.bat"

历史

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

显然,在更高版本中,不再需要其他cmd shell。

在早期,许多批处理文件取决于以下事实:调用批处理文件不会返回到调用批处理文件。在没有其他语法的情况下更改该行为将破坏许多系统,例如批处理菜单系统(将批处理文件用于菜单结构)。

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

提示

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

call "unit tests.bat"

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

FOR %x IN (*.bat) DO call "%x"

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

exit /B 1   # Or any other integer value in 0..255

返回错误级别。0表示正确执行。在调用批处理文件中,您可以使用

if errorlevel neq 0 <batch command>

if errorlevel 1如果您的Windows版本早于NT4 / 2000 / XP,则可以使用它来捕获所有1级及更高的错误级别。

为了控制批处理文件的流程,有goto :-(

if errorlevel 2 goto label2
if errorlevel 1 goto label1
...
:label1
...
:label2
...

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


同意,但是在这种情况下,循环可能会以错误的(字母顺序?)顺序处理文件
Dave Archer 2009年

很好,很完整的答案。如果要包括控制流,可能要注意的是,可以使用call:label1而不是goto来执行子例程,而批处理文件中的'return'语句则是有点奇怪的goto:eof(并且不需要自己制作一个eof标签(默认情况下存在)。
莱戈拉斯

errorlevel命令示例在Windows 10上(在cmd控制台中)给了我一个问题。我将命令修改为if errorlevel neq echo Houston We have a Problem!。我的批处理过程没有问题,并且基本上可以正常完成,但是在调用语句后使用此命令的方式的每个步骤中,我都得到“ neq这次是意外的”。我以为他们可能已经改变了不相等的语法,所以我尝试了一下!=<>但是对于新语法,仍然收到相同的“此时无法预期”错误。我可能做错了什么?
TMWP

117

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

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.

7
这就是我们的提示搜索,作为我们的第一个应用模块控制台,感谢
迈克尔·默勒

1
这将运行命令的多个实例,甚至可以运行具有<pause>的多个批处理文件。+1,因为这正是我正在寻找的解决方案!
克里斯蒂安·诺埃尔

5
您能否解释一下这些数字在您的答案中?他们的目的尚不清楚。
Kalamalka Kid

2
请注意,大多数人可能希望使用start "Window title" /wait cmd /k call something.bat以便按顺序运行事物。
安德鲁

2
(或者start "Window title" /wait cmd /c something.bat,在cmd /c关闭窗口一次完成)
安德鲁

42

尝试:

call msbuild.bat
call unit-tests.bat
call deploy.bat

28

您正在调用多个批处理以编译程序。我认为,如果发生错误:
1)批处理中的程序将以错误级别退出;
2)您想了解它。

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

'||' 测试错误级别是否高于0。这样可以按顺序调用所有批处理,但是将在发生任何错误时停止,从而使屏幕保持原样,以便您查看任何错误消息。


23

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

call aaa.bat
call bbb.bat

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

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

START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
  [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
  [/AFFINITY <hex affinity>] [/WAIT] [/B] [command/program]
  [parameters]

考试:

start /b aaa.bat
start /b bbb.bat

22
call msbuild.bat
call unit-tests.bat
call deploy.bat

20

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

call foo.bat

(是的,这很愚蠢,如果可以使用它来调用它foo.bat(像从命令提示符中进行调用那样会更有意义,但是正确的方法是使用call。)


7

查看文件名后,您是否考虑过使用诸如NAnt或Ant(Java版本)之类的构建工具。与bat文件相比,您将获得更多的控制权。


7

如果要一次打开许多批处理文件,则可以使用call命令。但是,call命令将关闭当前的bat文件并转到另一个文件。如果您想一次打开许多文件,则可以尝试以下操作:

@echo off
start cmd "call ex1.bat&ex2.bat&ex3.bat"

依此类推,或者对许多文件重复启动cmdcall...”。这适用于Windows 7,但我不确定其他系统。


6
Start msbuild.bat
Start unit-tests.bat
Start deploy.bat

如果那不起作用,请替换startcall或尝试以下操作:

Start msbuild.bat
Goto :1
:1
Start unit-tests.bat
Goto :2
:2
Start deploy.bat

3

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

call msbuild.bat
call unit-tests.bat
call deploy.bat

3

使用正确的报价(有时可能会很棘手):

start "" /D "C:\Program Files\ProgramToLaunch" "cmd.exe" "/c call ""C:\Program Files\ProgramToLaunch\programname.bat"""

第一个参数-标题(在这种情况下为空)
第二个参数-/ D指定开始目录,如果要当前的工作目录(例如“%〜dp0”)可以省略。
第三个参数-启动命令,“ cmd.exe”
第四arg-命令的参数,其中的参数加倍了引号(这是如何批量删除引号内的引号)


2

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

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

:: ScriptA.bat
Do Foo
EXIT
::ScriptB.bat
Do bar
EXIT

我删除了所有11条脚本EXIT行,然后再次尝试,所有11条脚本在同一命令窗口中一次一次运行。

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

::ScriptA.bat
Do Foo

::ScriptB.bat
Do bar

不要删除exitgoto :eof而是用代替。这将“返回”call
Stephan

您的确意识到,在简单的批处理命令中,命令将按照被称为命令的顺序运行,也就是索引的基本布局,@echo off :menu some commands goto menu请注意,这将连续不断地循环直到关闭。基本上,您不需要::正义:
CMS_95

0

以下解决了我的问题:

start call "batch1.bat"
start call "batch2.bat"

0

可能是您想要这样:

并行运行批处理脚本-

start "systemLogCollector" /min cmd /k call systemLogCollector.bat
start "uiLogCollector" /min cmd /k call uiLogCollector.bat
start "appLogCollector" /min cmd /k call appLogCollector.bat

这里,三个批处理文件以最小化状态在单独的命令窗口上运行。如果您不希望它们最小化,请删除/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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.