简体   繁体   English

无法从Win7中的主批处理文件顺序运行多个批处理文件

[英]Can't run multiple batch files sequentially from master batch file in Win7

I have a bunch of batch files that each start a bunch of executables to run concurrently. 我有一堆批处理文件,每个文件都启动一堆可执行文件来同时运行。 Each batch file starts 30 executables. 每个批处理文件启动30个可执行文件 When those 30 are done, I want the next batch of executables to run, again 30 at a time. 当这30个完成后,我希望下一批可执行文件再次运行30次。 The .exe's are called using the "start" command in the batch files and they work just fine - I can run the individual batch files for each group of 30 exe's and they run concurrently like they should. .exe是使用批处理文件中的“start”命令调用的,它们工作得很好 - 我可以为30个exe的每个组运行单独的批处理文件,它们可以同时运行。

I have created a "master" batch file that calls each sub-batch file but I can't figure out how to get it to run the sub-batch files in sequence, waiting for one to finish before starting the next. 我创建了一个“主”批处理文件,它调用每个子批处理文件,但我无法弄清楚如何让它按顺序运行子批处理文件,等待一个完成,然后再开始下一个。

If the master batch file is like this: 如果主批处理文件是这样的:

Batch1.bat
Batch2.bat
Batch3.bat

then only the first batch file is called - the others are never called. 然后只调用第一个批处理文件 - 其他文件永远不会被调用。

If the master batch file is like this: 如果主批处理文件是这样的:

call Batch1.bat
call Batch2.bat
call Batch3.bat

then all of the sub-batch files start running at the same time and I get hundreds of executables trying to start up at the same time. 然后所有子批处理文件同时开始运行,我得到数百个可执行文件同时尝试启动。

How do I make the master batch file call the first batch file, wait for it to finish, then call the next, wait for it to finish, then call the next, etc? 如何让主批处理文件调用第一个批处理文件,等待它完成,然后调用下一个,等待它完成,然后调用下一个等等?

Thanks in advance, 提前致谢,

rgames rgames

When starting another batch CALL will start it in the same window and the called batch has access to the same variable context. 当启动另一个批处理时,CALL将在同一窗口中启动它,并且被调用的批处理可以访问相同的变量上下文。 So it can also change variables which affects the caller. 因此它也可以更改影响调用者的变量。

Using wait in your batch file to call the executable will wait for them to exit before. 在批处理文件中使用wait来调用可执行文件将等待它们退出之前。

START /WAIT  batch1.bat
START /WAIT batch2.bat

Hope this helps 希望这可以帮助

Excuse me. 劳驾。 I think there is a misunderstanding here. 我觉得这里有一个误解。 If your master Batch file is this: 如果您的主批处理文件是这样的:

call Batch1.bat
call Batch2.bat
call Batch3.bat

then the Batch2.bat is called after Batch1.bat ends, and so on. 然后在Batch1.bat结束后调用Batch2.bat,依此类推。 You may do a small test to confirm this. 你可以做一个小测试来证实这一点。 On the other side, is possible that each BatchN.bat program uses the same variables? 另一方面,每个BatchN.bat程序可能使用相同的变量吗? If so, then the last values left from Batch1.bat may interfere with Batch2.bat, and so on. 如果是这样,那么Batch1.bat中剩下的最后一个值可能会干扰Batch2.bat,依此类推。 In this case, you must add a Setlocal command at beginning of each Batch file. 在这种情况下,您必须在每个批处理文件的开头添加Setlocal命令。

I had to run a data export program for several files. 我不得不为几个文件运行数据导出程序。 My solution: 我的解决方案

MasterBatch.bat: MasterBatch.bat:

@echo off
start /w batch1.bat
start /w batch2.bat

Batch1.bat Batch1.bat

@echo off
cmd /c "c: & cd Program Files (x86)/PATH & targetProgram.exe -parametersToExportVideo1"
EXIT

Batch2.bat Batch2.bat

@echo off
cmd /c "c: & cd Program Files (x86)/PATH & targetProgram.exe -parametersToExportVideo2"
EXIT

It may be adapted to run programs other problems. 它可能适用于运行程序其他问题。

You will have to create a signaling mechanism to aware EXE completation. 您将不得不创建一个信令机制来识别EXE completation。

I would create a third level batch to run each EXE, creating a temp file before executing EXE and deleting it after. 我会创建一个第三级批处理来运行每个EXE,在执行EXE之前创建临时文件并在之后删除它。

In sub-batch I would wait until there were no more temp files. 在子批处理中,我会等到没有更多的临时文件。

So, initial batch: 所以,初始批次:

call Batch1.bat
call Batch2.bat
call Batch3.bat

Sub-batch: 分批次:

Set Index=0
Call :Exec exefile1 args ...
Call :Exec exefile2 args ...
...
:WaitAll
If Exist %Temp%\RUNNING_EXE.*.TMP GoTo :WaitAll
GoTo :EOF

:Exec
Set /A Index+=1
Echo %Index% > %Temp%\RUNNING_EXE.%Index%.TMP
Start Batch_3rd.BAT %*
GoTo :EOF

Finally, 3rd level batch, Batch_3rd.BAT: 最后,第3级批处理,Batch_3rd.BAT:

%*
Del %Temp%\RUNNING_EXE.%Index%.TMP

%* are arguments passed from sub-batch (exe+arguments), %Index% is correct as start copies environment from sub-batch upon creation, and sub-batch don't change this copy. %*是从子批处理(exe +参数)传递的参数, %Index%在创建时从子批处理start复制环境是正确的,子批处理不会更改此副本。 One final note: you can probably merge all batches into a single batch file, calling it recursively. 最后一点:您可以将所有批次合并到一个批处理文件中,递归调用它。

My solution: 我的解决方案

1) I have four batch files: Parent.bat and Batch1.bat, Batch2.bat, Batch3.bat 1)我有四个批处理文件:Parent.bat和Batch1.bat,Batch2.bat,Batch3.bat

2) Parent.bat contains the below lines (take a close note): 2)Parent.bat包含以下行(请仔细注意):

call Batch1.bat > result1.log 调用Batch1.bat> result1.log

call Batch2.bat > result2.log 调用Batch2.bat> result2.log

call Batch3.bat > result3.log 调用Batch3.bat> result3.log

3) Make sure "into the end of Each Child batch file", you have an echo statement. 3)确保“在每个子批处理文件的末尾”,你有一个echo语句。 After this echo statement there shouldn't be any code... 在这个echo语句之后,不应该有任何代码......

Say content of Batch1.bat file is: 说Batch1.bat文件的内容是:

echo begin 回声开始

robocopy "C:\\Users\\DD\\Documents\\A" "C:\\Users\\DD\\Documents\\B" robocopy“C:\\ Users \\ DD \\ Documents \\ A”“C:\\ Users \\ DD \\ Documents \\ B”

echo end 回声结束

echo this_is_the_last_line echo this_is_the_last_line

Just for testing, i will use simple sub-batches like (all of them are the same) 只是为了测试,我将使用简单的子批次(所有这些都是相同的)

@echo off
    for /l %%a in (1 1 5) do start "" notepad.exe

And a master batch file 和一个主批处理文件

@echo off
    setlocal enableextensions disabledelayedexpansion

    set "flagFile=%temp%\%random%%random%%random%.tmp"

    for %%a in ( "batch1.cmd" "batch2.cmd" "batch3.cmd" ) do (
        call :startBatch %%a "%flagFile%"
    )

:retryClean
    echo %time% waiting for last batch to end
    2>nul ( 9>"%flagFile%" break ) || ( >nul timeout 5 & goto :retryClean )
    del /q "%flagFile%"

    echo DONE
    pause
    goto :eof

:startBatch batchFile flagFile
    echo %time% waiting to start "%~1"
    2>nul ( 9>"%~2" call "%~1" ) || ( >nul timeout 5 & goto :startBatch )
    echo %time% [ "%~1" ] STARTED
    goto :eof

This code starts each of the sub-batches with an active redirection (user available stream 9 is used) to a temporary flag file. 此代码使用活动重定向(使用用户可用流9)启动每个子批次到临时标志文件。 This will lock the flag file until all the processes started from sub-batches have ended as the redirection is inherited during the process creation. 这将锁定标志文件,直到从子批处理开始的所有进程都已结束,因为在创建进程期间继承了重定向。

All we have to do is to keep trying start the next batch file with the same redirection: 我们所要做的就是继续尝试使用相同的重定向启动下一个批处理文件:

  • If the file is still locked (processes are running), the batch file can not be started, wait 5 seconds and retry again 如果文件仍处于锁定状态(进程正在运行),则无法启动批处理文件,等待5秒钟并再次重试

  • If the file is not locked, the redirection can be created and the next batch file is started. 如果文件未锁定,则可以创建重定向并启动下一个批处理文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM