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

654 cmd batch-file

我正在尝试让我commit-build.bat执行其他.BAT文件作为构建过程的一部分.

内容commit-build.bat:

"msbuild.bat"
"unit-tests.bat"
"deploy.bat"
Run Code Online (Sandbox Code Playgroud)

这看起来很简单,但commit-build.bat只执行list(msbuild.bat)中的第一项.

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

Phi*_*ert 1119

使用:

call msbuild.bat
call unit-tests.bat
call deploy.bat
Run Code Online (Sandbox Code Playgroud)

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

  • 没有调用,根据原始DOS规范,应该执行命令链接而不返回.添加"CALL"之前的一个流行选项是打开一个子命令提示符,如"command/c second.bat",因为它也将返回. (6认同)
  • 在Windows 10上,只有第一行被执行.然而,farheen的答案奏效了. (5认同)
  • 如何将参数传递给批处理文件,其中一个参数是带空格的路径. (2认同)

Ral*_*ach 169

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

 call "msbuild.bat"
Run Code Online (Sandbox Code Playgroud)

历史

在古代DOS版本中,无法以递归方式执行批处理文件.然后引入了调用命令,该命令调用另一个cmd shell来执行批处理文件,并在完成时将执行返回给调用的cmd shell.

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

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

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

提示

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

call "unit tests.bat"
Run Code Online (Sandbox Code Playgroud)

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

FOR %x IN (*.bat) DO call "%x"
Run Code Online (Sandbox Code Playgroud)

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

exit /B 1   # Or any other integer value in 0..255
Run Code Online (Sandbox Code Playgroud)

给出一个错误级别.0表示正确执行.在调用批处理文件中,您可以使用

if errorlevel neq 0 <batch command>
Run Code Online (Sandbox Code Playgroud)

if errorlevel 1如果您使用比Windows NT4/2000/XP更旧的Windows来捕获所有错误级别1或更高级别,请使用此选项.

要控制批处理文件的流量,有goto :-(

if errorlevel 2 goto label2
if errorlevel 1 goto label1
...
:label1
...
:label2
...
Run Code Online (Sandbox Code Playgroud)

正如其他人所指出的那样:看一下构建系统来替换批处理文件.


far*_*een 111

如果我们想打开多个命令提示,那么我们可以使用

start cmd /k
Run Code Online (Sandbox Code Playgroud)

/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.
Run Code Online (Sandbox Code Playgroud)

  • 这是我们正在寻找的,因为我们的第一个应用程序阻止了控制台,感谢提示 (7认同)
  • 您能否解释一下这些数字在您的答案中?他们的目的尚不清楚。 (3认同)
  • 这将运行命令的多个实例,甚至可以运行具有 &lt;pause&gt; 的多个批处理文件。+1,因为这正是我正在寻找的解决方案! (2认同)
  • **请注意,大多数人可能想使用`start“窗口标题” / wait cmd / k调用something.bat`以便按顺序运行事物。** (2认同)
  • (或`开始“窗口标题” / wait cmd / c something.bat`,其中“ cmd / c`完成后关闭窗口) (2认同)

Jon*_*han 41

尝试:

call msbuild.bat
call unit-tests.bat
call deploy.bat
Run Code Online (Sandbox Code Playgroud)


Jay*_*Jay 27

您正在调用多个批处理以编译程序.我理所当然地认为如果发生错误:
1)批处理中的程序将以错误级别退出;
2)你想知道它.

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

'||' 测试错误级别高于0.这样所有批次都按顺序调用,但会在任何错误时停止,让屏幕保持原样,以便您查看任何错误消息.


but*_*ken 21

call msbuild.bat
call unit-tests.bat
call deploy.bat
Run Code Online (Sandbox Code Playgroud)


Zif*_*fre 19

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

call foo.bat
Run Code Online (Sandbox Code Playgroud)

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


小智 19

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

call aaa.bat
call bbb.bat
Run Code Online (Sandbox Code Playgroud)

执行脚本时,它将首先调用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]
Run Code Online (Sandbox Code Playgroud)

考试:

start /b aaa.bat
start /b bbb.bat
Run Code Online (Sandbox Code Playgroud)


Dav*_*her 7

查看文件名,您是否考虑过使用NAnt或Ant(Java版本)等构建工具.你将获得比bat文件更多的控制权.


小智 6

Start msbuild.bat
Start unit-tests.bat
Start deploy.bat
Run Code Online (Sandbox Code Playgroud)

如果还是不行,请更换startcall或试试这个:

Start msbuild.bat
Goto :1
:1
Start unit-tests.bat
Goto :2
:2
Start deploy.bat
Run Code Online (Sandbox Code Playgroud)


9pf*_*pfs 6

你的脚本应该是:

start "msbuild.bat"
start "unit-tests.bat"
start "deploy.bat"
Run Code Online (Sandbox Code Playgroud)


CMS*_*_95 5

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

@echo off
start cmd "call ex1.bat&ex2.bat&ex3.bat"
Run Code Online (Sandbox Code Playgroud)

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


Min*_*mal 5

并行运行多个批处理文件的最简单方法

start "systemLogCollector" /min cmd /k call systemLogCollector.bat
start "uiLogCollector" /min cmd /k call uiLogCollector.bat
start "appLogCollector" /min cmd /k call appLogCollector.bat
Run Code Online (Sandbox Code Playgroud)

运行多个批处理文件 这里三个批处理文件以最小化状态在单独的命令窗口上运行。如果您不希望它们最小化,请删除/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
Run Code Online (Sandbox Code Playgroud)


npo*_*aka 5

使用“ &

正如您已经注意到的情况下直接执行蝙蝠CALLSTARTCMD /C使作为第一个文件已完成输入和执行的第一个文件,然后进程停止。虽然您仍然可以使用&which 将与command1 & command2直接在控制台中使用相同:

(
    first.bat
)&(
    second.bat
)& (
    third.bat
)&(
    echo other commands
)
Run Code Online (Sandbox Code Playgroud)

就机器资源而言,这将是最有效的方式,尽管在最后一个块中您将无法使用命令行GOTO, SHIFT, SETLOCAL.. 并且其功能几乎与在命令提示符中执行命令相同。并且您将无法在最后一个右括号之后执行其他命令

使用 呼叫

call first.bat
call second.bat
call third.bat
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,这将是最好的方法 - 它不会创建单独的进程,但具有与调用:labelas 子例程几乎相同的行为。在 MS 术语中,它创建一个新的“批处理文件上下文并将控制权传递给指定标签后的语句。第一次遇到批处理文件的结尾(即跳转到标签后),控制返回到后面的语句通话声明。”

您可以使用在被调用文件中设置的变量(如果它们未在SETLOCAL块中设置),您可以直接访问被调用文件中的标签

CMD /C, 管道 ,FOR /F

其他native选项是使用CMD /C(/C 开关将强制被调用的控制台退出并返回控制) cmd.exe 以非透明方式执行的操作,使用FOR /Fbat 文件或使用管道时。这将产生一个子进程,它将拥有调用 bat 的所有环境。在资源方面效率较低,但由于进程是独立的,解析崩溃或调用EXIT命令不会停止调用 .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
Run Code Online (Sandbox Code Playgroud)

开始

允许您更灵活地在单独的窗口中启动脚本、不等待它们完成、设置标题等。默认情况下,它启动.bat.cmd脚本,CMD /K这意味着生成的脚本不会自动关闭。再次将所有环境传递给启动的脚本并消耗比cmd /c以下更多的资源:

:: 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
Run Code Online (Sandbox Code Playgroud)

无线麦克风

与现在的其他方法不同,这些示例将使用 CMD.exe 实用程序的外部(默认情况下仍可在 Windows 上使用)。WMIC 实用程序将创建完全独立的进程,因此您将无法直接等待完成。虽然 WMIC 的最佳特性是它返回生成的进程的 id:

:: 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%
Run Code Online (Sandbox Code Playgroud)

您还可以使用它在远程机器上启动一个进程,使用不同的用户等等。

计划任务

使用 SCHTASKS 提供了一些功能,如(明显的)调度、作为另一个用户(甚至是系统用户)运行、远程机器启动等。再次在完全独立的环境(即它自己的变量)中启动它,甚至是一个隐藏的进程、带有命令参数的 xml 文件等等:

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
Run Code Online (Sandbox Code Playgroud)

这里PID也可以从事件日志中获取。

ScriptRunner

在启动的脚本之间提供一些超时。基本事务功能(即错误回滚)和参数可以放在单独的 XML 文件中。

::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
Run Code Online (Sandbox Code Playgroud)