批处理%errorlevel%在FOR循环中返回0

时间:2011-08-21 14:57:57

标签: batch-file for-loop

我正在尝试创建一个循环,它将遍历指定目录中的一组文本文件,以搜索字符串。根据是否找到字符串报告结果。但是%errorlevel%总是返回0并且计算结果为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

4 个答案:

答案 0 :(得分:8)

%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
    )
     由于BOTH IF语句中的%VAR%

永远不会显示消息   在读取第一个IF语句时替换,因为它在逻辑上   包括IF的主体,这是一个复合语句。所以IF   复合语句中的内容实际上是在比较“之前”   “之后”永远不会平等。同样,以下示例   不会按预期工作:

    set LIST=
    for %i in (*) do set LIST=%LIST% %i
    echo %LIST%
     

因为它不会在当前目录中建立文件列表,   但是只需将LIST变量设置为找到的最后一个文件。   同样,这是因为%LIST%在FOR时仅扩展一次   读取语句,此时LIST变量为空。所以   我们正在执行的实际FOR循环是:

    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循环是:

    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%

答案 1 :(得分:4)

我更喜欢让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

答案 2 :(得分:2)

正如雷蒙德所说,你正在为回声评估%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
    )
)

答案 3 :(得分:0)

我在循环注册表项/值时遇到了同样的问题,并且发表了这篇文章。我的“reg query”在for循环中总是有ERRORLEVEL 0。

这是我的解决方案:

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{ [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { //change constraints }]; }

KEY64是HKLM \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall