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 循环中转到标签 - 这根本行不通。FOR 循环执行 GOTO 的那一刻,循环终止,FOR 上下文丢失。所以你的%%aFOR 变量不再被定义。IF 语句也会发生类似的问题,如(Windows 批处理) Goto inside if block 中所述,它的行为非常奇怪

当您尝试%checker%在设置值的同一个带括号的代码块内展开时,您也会遇到问题。这种扩展发生在解析时,整个块被一次解析。因此,您看到的值将始终是输入块之前存在的值。解决方案是启用延迟扩展和使用!checker!,而不是%checker%.

就个人而言,我可能会对您的代码进行重大更改。但我相信以下最小的更改可以使您的代码工作,假设没有其他错误:

  • 启用延迟扩展
  • 将您的 DO 循环代码移动到循环外部的例程中,然后让循环调用该例程并将%%a其作为参数。CALL 不会中断循环。
  • 代替例行公事%1_%%a
  • 代替. exit /b_ goto 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 回答