0

私は次のようなことをしたいと思います:

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
4

2 に答える 2

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 ...すべてが終了するまで、それはさらに続くだけです。

于 2012-07-26T05:51:59.647 に答える
1

Joeyが提案した方法は機能しますが、プログラムを複数回起動できると問題が発生する可能性があります。監視したいタスクが1回であるかどうかを判断するのが難しくなります。

各プログラムは、プログラムが終了するまで、一時出力ファイルを排他的にロックします。別のプロセスが同じファイルにリダイレクトしようとすると失敗します。これは、プログラムがいつ終了したかを検出するために使用できます。

TIMEOUTを使用して、ポーリングに遅延を挿入しました。TIMEOUTがないXPのようなシステムを使用している場合は、ping -n 2 ::1 >nul 2>nul代わりに使用できます。

このソリューションがどのように機能するかについての広範なドキュメントをコードに含めました。編集-不要なコードブロックレベルを1つ削除することでコードを少し簡略化し、ドキュメントを改善しました。

@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%*"
于 2012-07-26T18:10:45.637 に答える