4

On my desktop, there is a folder named "test". Inside this folder is two files, "file1.txt" and "file2.txt".

Take a look at this simple batch script:

@ECHO OFF

SET test="C:\Users\Tyler\Desktop\test"

ECHO %test%
FOR /R %test% %%F IN (*) DO (
    ECHO %%F
)

As you might expect, it outputs the following:

"C:\Users\Tyler\Desktop\test"
C:\Users\Tyler\Desktop\test\file1.txt
C:\Users\Tyler\Desktop\test\file2.txt

Now take a look at this variation:

@ECHO OFF

SETLOCAL ENABLEDELAYEDEXPANSION

SET test="C:\Users\Tyler\Desktop\test"

ECHO !test!
FOR /R !test! %%F IN (*) DO (
    ECHO %%F
)

ENDLOCAL

I would expect its output to be no different. However, here it is:

"C:\Users\Tyler\Desktop\test"

It appears that !test! gets expanded in the ECHO !test! line, but not in the FOR /R !test! line, becoming just !test!. Since that is, of course, not a valid path, the FOR /R loop never iterates.

Why is this? What am I missing?

TSmith
  • 285
  • 2
  • 9

1 Answers1

5

Why FOR works different than ECHO is because the batch parser (cmd.exe) has special parsing rules for FOR, IF and REM.

Therefore delayed expansion doesn't work for the parameters here, only for the arguments inside the parenthesis.

Only percent expansion works for the parameters, as the parser executes the percent expansion phase just before it switches to the special FOR parser rules.

If you can't use percent expansion, as you are inside of a block you can move the code to an own function and call it.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET test="C:\Users\Tyler\Desktop\test"

ECHO !test!
call :doMyLoop test
exit /b

:doMyLoop
set "arg=!%1!"
FOR /R %arg% %%F IN (*) DO (
    ECHO %%F
)
Community
  • 1
  • 1
jeb
  • 70,992
  • 15
  • 159
  • 202