errorlevel in for loop returns exit code of iterating statement

It turns out that errorlevel is returning the exit code of iterating statement in the for loop instead of the one immediately preceding it.

for /r \\computer\share\x86 %%x in (*.xml) do (

IsVarMap.exe /file:"%%x"

    echo %ERRORLEVEL%

)

Echoes 0 always. I expect some iterations to return 2, when xml file isn’t a VarMap.

IsVarMap.exe /file:notavarmap.xml

echo %ERRORLEVEL%

Echoes 2 as expected

Comments

  • Anonymous
    January 01, 2003
    This behavior actually makes the FOR /L construct unusable except in trivial cases.  the setlocal enabledelayedexpansion will only work in some cases as well (a subshell seems to break it) and even the :: comment char seems to break inside a for loop. I was writing a startup script to handle startup service dependencies that a couple foreground apps have and I thought nice we have a real for loop construct in cmd files in XP/2003!  Alas, the following doesn't work: SET PS=powershell -nologo -command SET Sleep=timeout /nobreak /t setlocal enabledelayedexpansion FOR /L %%i (1,1,5) DO (    SET SVC=MSSQLSERVER    %PS% "& {if((get-service %SVC%).Status -eq 'Running') {Exit 1}}" > NUL    IF !ERRORLEVEL! EQU 1 GOTO :NextTest    ECHO.  Sleeping 5 seconds...    %Sleep% 5 2>&1> NUL ) endlocal REM Woopsie, never get here 'cause we loop forever since %%i goes undefined GOTO :ServiceStartupTimeout :NextTest REM Woopsie, we get here one loop late if %SVC% is Running  This is because %%i goes undefined REM after a subshell is used. When %%i is undef, then %ERRORLEVEL% and !ERRORLEVEL! == 1 REM Note this makes the service testing useless because we always escape the loop even if the service isn't REM running. :ServiceStartupTimeout ECHO.Timed out waiting for services to start. GOTO :EOF :EOF The above problems are all fixed when you enclose the testing inside a SET /A construct like this: @ECHO off SET i=0 SET iMax=12 :TestSQL    SET SVC=MSSQLSERVER    %PS% "& {if((get-service %SVC%).Status -eq 'Running') {Exit 1}}" > NUL    IF !ERRORLEVEL! EQU 1 GOTO :NextTest        IF %i% == %iMax% GOTO :TestSQL_End    SET /A i=%i% + 1    ECHO.  Sleeping 5 seconds...    %Sleep% 5 2>&1> NUL    GOTO :TestSQL :TestSQL_End GOTO :ServiceStartupTimeout :NextTest ... Makes one wonder, why not just use powershell for the whole thing eh?  Of course they could just fix sc query so contortions aren't necc. to get a service status!

  • Anonymous
    January 01, 2003
    And its logical consequences.

  • Anonymous
    June 13, 2006
    The comment has been removed

  • Anonymous
    July 17, 2014
    for /r \computersharex86 %%x in (*.xml) do (CALL :ISVARMAP "%%x")
    exit
    :ISVARMAP
    IsVarMap.exe /file:"%~1"
    echo %ERRORLEVEL%
    goto :EOF