批处理%errorlevel%在FOR循环中返回0
我想要做一个循环,将通过搜索字符串的指定目录中的一组文本文件。根据是否找到字符串来报告结果。但%errorlevel%
总是返回0,计算结果为0。批处理%errorlevel%在FOR循环中返回0
SETLOCAL enabledelayedexpansion
FOR %%G IN (*.txt) DO (
find /i "My text string" "%%G"
ECHO %date% %time% : errorlevel is %errorlevel% >> %report_dir%\%computername%.txt
IF %errorlevel% EQU 1 (
ECHO %date% %time% : String found >> %report_dir%\%computername%.txt
GOTO:copy_log
)
)
ENDLOCAL
雷蒙德做你的意思是?:
SETLOCAL enabledelayedexpansion
FOR %%G IN (*.txt) DO (
find /i "My text string" "%%G"
IF %errorlevel% (
ECHO %date% %time% : String found >> %report_dir%\%computername%.txt
GOTO:copy_log
)
)
ENDLOCAL
我宁愿让For
循环调用分支。它可以防止可变的扩展问题:
For %%G In (*.txt) Do Call :ScanFile "%%G"
Exit /B
:ScanFile
Find /i "My text string" "%~1"
If %ErrorLevel%==1 (
Echo %date% %time% : String found >> %report_dir%\%computername%.txt
Goto :CopyLog
)
Exit /B
:CopyLog
...
Exit /B
这是最简单的解决方案。谢谢。 – Dean
%ERRORLEVEL%
被过早地扩大。您只需避免问题完全由使用:
IF ERRORLEVEL 1
或进一步详情,请参阅“延迟环境变量扩充”从SET /?
帮助文本这样的解释:
最后,支持对于延迟环境变量扩展已添加 。默认情况下,此支持始终处于禁用状态,但可能通过
/V
命令行切换到CMD.EXE启用/禁用 。见CMD /?
延迟环境变量扩充是获取当前扩大而不是在执行它恰好在 一行文本阅读,围绕 局限性有用。下面的示例 显示了与即时变量扩展问题:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked )
绝不会显示该消息,因为在这两种IF语句 是取代的IF语句被读取时,第一
%VAR%
,因为它在逻辑上 包括主体的IF,这是一个复合陈述。因此,复合陈述中的IF 确实比较“之前”与 “之后”,这将永远不会相等。同样,预计下面的例子 将不起作用:的是,它不会建立文件列表在当前目录下,set LIST= for %i in (*) do set LIST=%LIST% %i echo %LIST%
而是将只设置LIST变量找到的最后一个文件。 同样,这是因为当读取FOR 语句时,%LIST%仅展开一次,并且此时LIST变量为空。所以 ,我们真正执行的循环是:
for %i in (*) do set LIST= %i
这个循环继续将LIST到找到的最后一个文件。
延迟的环境变量扩展允许您使用不同的 字符(感叹号)来扩展环境变量,执行时间为 。如果延迟变量扩充被启用,如预期上述 例子可以写成如下工作:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked )
再次,这是因为%LIST%扩大只是一次当FOR 声明被读取,那时LIST变量是空的。所以 ,我们真正执行的循环是:
for %i in (*) do set LIST= %i
这个循环继续将LIST到找到的最后一个文件。
延迟的环境变量扩展允许您使用不同的 字符(感叹号)来扩展环境变量,执行时间为 。如果延迟变量扩充被启用,如预期上述 例子可以写成如下工作:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked ) set LIST= for %i in (*) do set LIST=!LIST! %i echo %LIST%
正如雷蒙说,你正在评估%ERRORLEVEL%的回声,它几乎总是(永远说永不)返回沿下面的线为0
的事情会做的更好:
FOR %%G IN (*.txt) DO (
find /i "My text string" "%%G"
SET error = %errorlevel%
ECHO %date% %time% : errorlevel is %errorl% >> %report_dir%\%computername%.txt
IF %error% EQU 1 (
ECHO %date% %time% : String found >> %report_dir%\%computername%.txt
GOTO:copy_log
)
)
我在通过注册表项/值进行循环时遇到了同样的问题,并且来到这篇文章。我的“reg查询”在for循环中总是有ERRORLEVEL 0。
这里是我的解决方案:
for %%s in (%ToBeUninstalled%) do ( REG QUERY "%KEY64%\%%s" | find /i "UninstallString" > NUL && (msiexec.exe /x %%s /qb) || (echo Software not installed) )
KEY64是HKLM \ SOFTWARE \ Wow6432Node \微软\的Windows \ CurrentVersion \卸载
如文档中提到,您使用感叹号的延迟扩展和百分比立即扩张的迹象。你仍然在使用'%ERRORLEVEL%',它会立即被扩展。你想延迟,所以你需要'!ERRORLEVEL!'。或者你可以通过说'IF ERRORLEVEL 1'来避免整个问题。 –