Home > Net >  BATCH why does running this FOR loop inside an IF statement not work until I run it once outside of
BATCH why does running this FOR loop inside an IF statement not work until I run it once outside of

Time:01-27

I've been racking my head over my script on why the section for finding out the directory size in bytes does not work but after a long time of debugging i've encountered the following scenario:

  • if I run the for loop inside an IF statement it doesn't work
  • if I run the for loop outside the IF statement it does work
  • if I run the for loop outside the IF statement and then run it inside afterwards, it does work

Is the for loop written incorrectly or am I misunderstanding or missing something?

The following does NOT work

@ECHO OFF

set "test=1"

if %test% GTR 0 (
    
    echo Scenario A
    
    pushd "%~dp0"
    set dir="C:\temp"
    for /f "tokens=3" %%i in ('robocopy /l /e /bytes %dir% %dir% ^| findstr Bytes') do set size=%%i
    echo Size = %size%

    pause

) else (
    
    echo Scenario B
    pause

)

But this DOES work for both runs

@ECHO OFF

set "test=1"

echo Method a

    pushd "%~dp0"
    set dir="C:\temp""
    for /f "tokens=3" %%i in ('robocopy /l /e /bytes %dir% %dir% ^| findstr Bytes') do set size=%%i
    echo Size = %size%

echo Now Method A in IF statement

if %test% GTR 0 (
    
    echo Scenario A
    
    pushd "%~dp0"
    set dir="C:\temp"
    for /f "tokens=3" %%i in ('robocopy /l /e /bytes %dir% %dir% ^| findstr Bytes') do set size=%%i
    echo Size = %size%

    pause

) else (
    
    echo Scenario B
    pause

)

CodePudding user response:

The reason is that variables in if/else statement are expanded before executing it. You are setting dir variable inside it, but all %dir% occurrences are expanded at the same time, before running if/else.

Basically the following command is actually executed. As you can see all variables were expanded:

if 1 GTR 0 (
    echo Scenario A
    pushd "C:\Workdir\"
    set dir="C:\temp"
    for /f "tokens=3" %i in ('robocopy /l /e /bytes | findstr Bytes') do set size=%i
    echo Size = 
    pause
) else (
    echo Scenario B
    pause
)

As an alternative you can use if/goto commands to organize the flow. In this case every command will be expanded individually. It will look like this:

if %test% NEQ 1 goto ScenarioB
rem Scenario A
goto Done

:ScenarioB
rem Scenario B
:Done

Also double quotes are not needed in set test=1.

To troubleshoot such issues you can turn echo on, then you will see the commands being executed.

  • Related