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语句也会出现类似的问
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