For loop Windows批处理For循环:以下代码有问题

For loop Windows批处理For循环:以下代码有问题,for-loop,batch-file,For Loop,Batch File,上述代码将执行以下操作: 解析变量名称列表(其中内容用空格分隔) 检查%%a_Logs.txt文件中是否存在“已完成” 如果它存在,则进行迭代,如果不存在,则检查同一文件中的字符串“ERROR” 若存在错误,则输出错误消息并结束迭代 如果未发现错误,则在结束迭代前继续复查120秒 我一直得到以下输出 FINDSTR:无法打开%a_Logs.txt您试图转到FOR循环中的标签-这根本不起作用。FOR循环执行GOTO时,循环终止,FOR上下文丢失。因此,变量的%%a不再定义。IF语句也会出现类似的问

上述代码将执行以下操作:

  • 解析变量名称列表(其中内容用空格分隔)
  • 检查%%a_Logs.txt文件中是否存在“已完成”
  • 如果它存在,则进行迭代,如果不存在,则检查同一文件中的字符串“ERROR”
  • 若存在错误,则输出错误消息并结束迭代
  • 如果未发现错误,则在结束迭代前继续复查120秒
  • 我一直得到以下输出


    FINDSTR:无法打开%a_Logs.txt

    您试图转到FOR循环中的标签-这根本不起作用。FOR循环执行GOTO时,循环终止,FOR上下文丢失。因此,变量的
    %%a
    不再定义。IF语句也会出现类似的问题,如中所述

    当您试图在设置值的同一括号代码块内展开
    %checker%
    时,也会出现问题。该扩展在解析时发生,并且立即解析整个块。因此,您看到的值将始终是输入块之前存在的值。解决方案是启用延迟扩展并使用
    !检查器而不是
    %checker%

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

    • 启用延迟扩展
    • 将DO循环代码移动到循环外的例程,然后让循环调用该例程,并将
      %%a
      作为参数。调用不会中断循环
    • 将例程中的
      %%a
      替换为
      %1
    • goto endLoop
      替换
      exit/b
      。同时将
      退出/b
      放在例程的末尾
    • 当FOR循环完成时,确保代码不会落入例程。我在FOR循环之后使用了GOTO
    • 替换
      !检查器用于
      %checker%
    • EDIT-必须转义ECHO语句中的
    这是修改后的代码(未测试)


    您试图转到FOR循环中的标签-这根本不起作用。FOR循环执行GOTO时,循环终止,FOR上下文丢失。因此,变量的
    %%a
    不再定义。IF语句也会出现类似的问题,如中所述

    当您试图在设置值的同一括号代码块内展开
    %checker%
    时,也会出现问题。该扩展在解析时发生,并且立即解析整个块。因此,您看到的值将始终是输入块之前存在的值。解决方案是启用延迟扩展并使用
    !检查器而不是
    %checker%

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

    • 启用延迟扩展
    • 将DO循环代码移动到循环外的例程,然后让循环调用该例程,并将
      %%a
      作为参数。调用不会中断循环
    • 将例程中的
      %%a
      替换为
      %1
    • goto endLoop
      替换
      exit/b
      。同时将
      退出/b
      放在例程的末尾
    • 当FOR循环完成时,确保代码不会落入例程。我在FOR循环之后使用了GOTO
    • 替换
      !检查器用于
      %checker%
    • EDIT-必须转义ECHO语句中的
    这是修改后的代码(未测试)


    我认为你的for循环中的标签把它搞乱了。我只是尝试将循环的内容移动到一个单独的“子例程”中,这样就消除了您提到的错误

    试试这个:

    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
    

    我认为你的for循环中的标签把它搞乱了。我只是尝试将循环的内容移动到一个单独的“子例程”中,这样就消除了您提到的错误

    试试这个:

    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
    

    晚了几分钟,但还是+1:-)OP的代码还有其他问题。看,太有趣了——我整天都在重复这个问题,被打断了。当我最终完成我的答案并点击提交时,你的答案在一分钟前就通过了。:-)无论如何,你的答案更完整,所以我也会加1。晚了几分钟,但还是加1:-)OP的代码还有其他问题。看,太有趣了——我整天都在重复这个问题,被打断了。当我最终完成我的答案并点击提交时,你的答案在一分钟前就通过了。:-)你的答案更完整,所以我也加了1。还有一个错误,如果你在for循环中使用变量而不是文件,你需要用双引号括起来。我不能给你举一个例子,因为我在打电话。哦,你需要在echo命令中转义括号。@ProfPickle-很好地抓住了未转义的
    ,我已经更新了答案。但是,对于FOR语句中需要的引号,您是错的。这是一个简单的FOR循环,它迭代IN()子句中以空格分隔的标记,而不是用于/F解析字符串值。变量周围的引号将破坏功能,因为整个内容将被视为一个令牌。非常感谢大家!我刚刚意识到我在for循环中使用goto的错误。你的解决方案很好。我已经对它进行了测试,它是有效的。@Varun_S-如果你得到了满意的答案,你应该点击左上角附近的复选标记来接受答案。这样做会让其他人知道问题已经得到了回答,它会给你2点声誉积分,给回答者15分
    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