我正在尝试让我commit-build.bat
执行其他.BAT文件,这是我们构建过程的一部分。
内容commit-build.bat
:
"msbuild.bat"
"unit-tests.bat"
"deploy.bat"
这似乎很简单,但是commit-build.bat
只执行列表(msbuild.bat
)中的第一项。
我已经分别运行每个文件,没有问题。
我正在尝试让我commit-build.bat
执行其他.BAT文件,这是我们构建过程的一部分。
内容commit-build.bat
:
"msbuild.bat"
"unit-tests.bat"
"deploy.bat"
这似乎很简单,但是commit-build.bat
只执行列表(msbuild.bat
)中的第一项。
我已经分别运行每个文件,没有问题。
Answers:
采用:
call msbuild.bat
call unit-tests.bat
call deploy.bat
不使用CALL时,当前的批处理文件将停止并且被调用的批处理文件开始执行。这是可以追溯到早期MS-DOS时代的一种特殊行为。
所有其他答案都是正确的:使用通话。例如:
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
...
正如其他人指出的:看一下替换批处理文件的构建系统。
errorlevel
命令示例在Windows 10上(在cmd控制台中)给了我一个问题。我将命令修改为if errorlevel neq echo Houston We have a Problem!
。我的批处理过程没有问题,并且基本上可以正常完成,但是在调用语句后使用此命令的方式的每个步骤中,我都得到“ neq这次是意外的”。我以为他们可能已经改变了不相等的语法,所以我尝试了一下!=
,<>
但是对于新语法,仍然收到相同的“此时无法预期”错误。我可能做错了什么?
如果我们要打开多个命令提示符,则可以使用
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.
start "Window title" /wait cmd /k call something.bat
以便按顺序运行事物。
start "Window title" /wait cmd /c something.bat
,在cmd /c
关闭窗口一次完成)
如果我们有两个批处理脚本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
使用正确的报价(有时可能会很棘手):
start "" /D "C:\Program Files\ProgramToLaunch" "cmd.exe" "/c call ""C:\Program Files\ProgramToLaunch\programname.bat"""
第一个参数-标题(在这种情况下为空)
第二个参数-/ D指定开始目录,如果要当前的工作目录(例如“%〜dp0”)可以省略。
第三个参数-启动命令,“ cmd.exe”
第四arg-命令的参数,其中的参数加倍了引号(这是如何批量删除引号内的引号)
在一个脚本中运行多个脚本我遇到了同样的问题。我一直让它死在第一个脚本上,却没有意识到它正在第一个脚本上退出。
:: 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
exit
,goto :eof
而是用代替。这将“返回”call
@echo off :menu some commands goto menu
请注意,这将连续不断地循环直到关闭。基本上,您不需要::
正义:
并行运行批处理脚本-
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