0
    set checker=0

for %%a in (%namelist%) do (
:startLoop
    findstr "completed" %%a_Logs.txt
    IF ERRORLEVEL 1 (
        IF %checker%==120 (
            set checker=0
            goto endLoop
        )
        set /a checker=%checker%+1
        @ping 127.0.0.1 -n 1 -w 1000 > nul
        findstr "ERROR" %%a_Logs.txt
        IF ERRORLEVEL 1 (
            echo Waiting 1 second before rechecking (Max 2 mins)
            echo time elapsed %checker% seconds
            echo.
            goto startLoop
        )
        findstr "ERROR" %%a_Logs.txt
        IF NOT ERRORLEVEL 1 (
            echo ERROR: %%a Error found
            goto endLoop
        )
    )
    findstr "completed" %%a_Logs.txt
    IF NOT ERRORLEVEL 1 (
        echo %%a completed
    )
:endLoop
)

上記のコードは、次のことを実行します。

  1. 変数名リストを解析します(内容はスペースで区切られます)
  2. 「完了」が%%a_Logs.txtファイルに存在するかどうかを確認します
  3. 存在する場合は繰り返し、存在しない場合は同じファイルで文字列「ERROR」を確認します
  4. ERRORが存在する場合は、ERROR MSGを出力し、反復を終了します
  5. ERRORが見つからない場合は、反復を終了する前に、次の120秒間再チェックを続けてください

私は次の出力を取得し続けます

FINDSTR:%a_Logs.txtを開くことができません

4

2 に答える 2

4

FORループ内でラベルをGOTOしようとしていますが、これは単に機能しません。FORループがGOTOを実行すると、ループが終了し、FORコンテキストが失われます。したがって、%%aFOR変数は定義されなくなります。同様の問題は、(Windowsバッチ)ifブロック内のGotoで説明されているように、IFステートメントでも発生します。

%checker%値を設定するのと同じ括弧で囲まれたコードブロック内で展開しようとすると、問題も発生します。その拡張は解析時に発生し、ブロック全体が一度に解析されます。したがって、表示される値は常に、ブロックが入力される前に存在していた値になります。解決策は、遅延拡張を有効にして、!checker!の代わりに使用することです%checker%

個人的に、私はおそらくあなたのコードに重要な変更を加えるでしょう。ただし、他にバグがないと仮定すると、次の最小限の変更でコードを機能させることができると思います。

  • 遅延拡張を有効にする
  • DOループコードをループ外のルーチンに移動してから、ループでそのルーチンを%%aパラメーターとしてCALLします。CALLはループを中断しません。
  • ルーチンの代わり%1%%a
  • の代わりexit /bgoto endLoop。またexit /b、ルーチンの最後に置きます
  • FORループが終了したときに、コードがルーチンに該当しないことを確認してください。FORループの後にGOTOを使用しました
  • 代用!checker!_%checker%
  • 編集 -ECHO)ステートメントのをエスケープする必要があります

これが変更されたコードです(テストされていません)

setlocal enableDelayedExpansion
set checker=0
for %%a in (%namelist%) do call :startLoop %%a
goto continue

:startLoop
findstr "completed" %1_Logs.txt
IF ERRORLEVEL 1 (
    IF !checker!==120 (
        set checker=0
        exit /b
    )
    set /a checker=checker+1
    @ping 127.0.0.1 -n 1 -w 1000 > nul
    findstr "ERROR" %1_Logs.txt
    IF ERRORLEVEL 1 (
        echo Waiting 1 second before rechecking (Max 2 mins^)
        echo time elapsed !checker! seconds
        echo.
        goto startLoop
    )
    findstr "ERROR" %1_Logs.txt
    IF NOT ERRORLEVEL 1 (
        echo ERROR: %1 Error found
        exit /b
    )
)
findstr "completed" %1_Logs.txt
IF NOT ERRORLEVEL 1 (
    echo %1 completed
)
exit /b

:continue
于 2013-02-26T23:42:38.313 に答える
2

forループ内のラベルがそれを台無しにしていると思います。ループの内容を別の「サブルーチン」に移動してみたところ、あなたが言及したエラーが取り除かれました。

これを試して:

set checker=0

for %%a in (foo bar baz) do (
    call :loop %%a
)
goto :eof

:loop
set basename=%1
:startLoop
findstr "completed" %basename%_Logs.txt
IF ERRORLEVEL 1 (
    IF %checker%==120 (
        set checker=0
        goto endLoop
    )
    set /a checker=%checker%+1
    @ping 127.0.0.1 -n 1 -w 1000 > nul
    findstr "ERROR" %basename%_Logs.txt
    IF ERRORLEVEL 1 (
        echo Waiting 1 second before rechecking (Max 2 mins)
        echo time elapsed %checker% seconds
        echo.
        goto startLoop
    )
    findstr "ERROR" %basename%_Logs.txt
    IF NOT ERRORLEVEL 1 (
        echo ERROR: %basename% Error found
        goto endLoop
    )
)
findstr "completed" %basename%_Logs.txt
IF NOT ERRORLEVEL 1 (
    echo %basename% completed
)
:endLoop
goto :eof
于 2013-02-26T23:44:28.443 に答える