Search code examples
windowsvariablesbatch-filejobsoverwrite

Why isn't my BAT file variable being overwritten?


I have this block of code:

@ECHO OFF

SET "SRCFOLDER=C:\Users\MyUserName\Desktop\PhotoTests"

SET "TEMPCODE=Hi"
ECHO %TEMPCODE%
ECHO.

FOR /F "tokens=*" %%G IN ('DIR /B %SRCFOLDER%') DO (
    ECHO %%G
    CALL tooltipInfo.bat %%G 19 | FIND /C "Star" > test.txt
    SET /P TEMPCODE=<test.txt
    ECHO %TEMPCODE%
    ECHO.
)

SET /P TEMPCODE=<test.txt
ECHO %TEMPCODE%
ECHO.

PAUSE

I'm confused by the output as I noticed that the variable in the FOR loop is not overwritten by what I think should be the content of "test.txt", which will vary each time the FOR loop runs.

For the purpose of this example, the file tooltipInfo.bat will echo a text string like "1 Star" or "3 Stars" based on the rating recorded in the file's properties. The FIND statement should result in a "0" or "1" being saved into the test.txt file.

The output is:

Hi

Canon_Locked.JPG
Hi

Nikon_Locked.JPG
Hi

0

Press any key to continue . . .

May I know why the TEMPCODE variable isn't being overwritten in the loop and retains the original value of "Hi". However in the final block of code, it was able to read and echo out the actual content of the file.


Solution

  • This is a common mistake when using FOR and parentheses. The problem is that by default every variable between ( and ) is evaluated when the line is first read, and then re-used for each iteration of the FOR.

    If the variable changes during the loop (via SET), then you will need to change % to ! for variables inside the parentheses, and also turn on delayed expansion using setlocal

    SETLOCAL enabledelayedexpansion
    FOR /F "tokens=*" %%G IN ('DIR /B %SRCFOLDER%') DO (
        ECHO %%G
        CALL tooltipInfo.bat %%G 19 | FIND /C "Star" > test.txt
        SET /P TEMPCODE=<test.txt
        ECHO !TEMPCODE!
        ECHO.
    )