我想做点什么:
start program1 ^>output
start program2 ^>output
并对输出进行排序,以便对输出进行排序。我不关心哪个输出是第一个(program1或program2),但我希望它是该程序输出的完整转储。
理想情况下,我希望并行运行多个程序,并将所有内容输出到屏幕,但文件可以正常运行。我不需要在它运行时看到它,只是在它完成时才能理解它。
编辑:
如果我按照建议将它们输出到一个文件然后在它完成时合并它,我就会等到所有程序都完成了 - 所以,我需要一个waitUntilAllTheStartsAreFinished命令。
start program1 ^>output1
start program2 ^>output2
#... as many as I need
waitUntilAllTheStartsAreFinished
TYPE output1
TYPE output2
delete output1
delete output2
答案 0 :(得分:2)
您可以使用循环和tasklist
:
:wait
rem just wait a second before looking again
ping -n 2 ::1 >nul 2>nul
tasklist 2>&1 | findstr /b "program1.exe program2.exe ..." >nul 2>&1 && goto wait
只有在program1.exe program2.exe ...
全部终止后才会继续。
答案 1 :(得分:1)
Joey建议的方法可行,但如果您的程序可以多次启动,则可能会出现问题。很难分辨哪些任务是您要监控的内容。
每个程序都会对临时输出文件进行独占锁定,直到程序完成。另一个进程重定向到同一文件的任何尝试都将失败。这可用于检测程序何时完成。
我使用TIMEOUT在轮询中插入延迟。如果您使用的是没有TIMEOUT的XP系统,那么您可以使用ping -n 2 ::1 >nul 2>nul
代替。
我已经在代码中包含了有关此解决方案如何工作的大量文档。 编辑 - 我通过删除一个不必要的代码块级别来简化代码,并改进了文档。
@echo off
setlocal
REM Define a base name for the temporary output files. I've incorporated
REM a random number in the file name to generally make it safe to run this
REM master script multiple times simultaneously. It is unlikely a collision
REM will occur, but incorporating a timestamp in the name would make it more
REM reliable.
set "baseName=%temp%\output%random%_"
set /a "progCount=2, completedCount=0"
REM Start each program with both stdout and stderr redirected to a temporary
REM ouptut file. The program will have an exclusive lock on the output file
REM until it finishes executing. I've assumed the program is another batch file
REM and I use the START /B switch so that the programs are run in the same
REM window as this master script. Any console program will work, and the
REM /B switch is optional.
start /b "" ^"cmd /c test.bat ^>"%baseName%1" 2^>^&1^"
start /b "" ^"cmd /c test2.bat ^>"%baseName%2" 2^>^&1^"
REM etc.
REM Clear any existing completed flags, just in case
for /l %%N in (1 1 %progCount%) do set "completed%%N="
:loopUntilDone
REM Introduce a delay so we don't inundate the CPU while we poll
timeout /nobreak 1 >nul
REM Loop through each of the output file numbers.
REM Redirect the stderr for the DO block to nul so that if the inner
REM block redirection fails, the error message will be suppressed.
for /l %%N in (1 1 %progCount%) do (
REM Only test this particular program if the output file has been
REM created (in other words, the program has started) and we haven't
REM already detected that it has finished. Also redirect an unused
REM file handle to the output file in append mode. The redirection will
REM fail if the program has not completed. If the redirection fails then
REM the IF block is not executed.
if not defined completed%%N if exist "%baseName%%%N" (
REM We are within the block, meaning the redirection succeeded and
REM the program must have finished. So print out the results.
echo(
echo Ouput for program%%N
echo ---------------------------------------------
type "%baseName%%%N"
REM Set a flag so we know this program has finished
set completed%%N=1
REM Increment the completed count so we know when we are done
set /a completedCount+=1
) 9>>"%baseName%%%N"
) 2>nul
if %completedCount% neq %progCount% goto :loopUntilDone
del "%baseName%*"