Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Batch file variables initialized in a for loop

I have a batch file which initializes variables via SET inside a for loop, for a set of files on disk:

for %%f in (%MYTARGETDIR%\*config.xml) do (
  SET TMPFILE=%%F.tmp

  echo In loop %TMPFILE%
)

echo End loop %TMPFILE%

when I run this in a brand new command shell (without TMPFILE defined) the In loop echo is empty, but the end loop echo is not.

When I run a second time, its already set, and outputs its value, ignoring the set until the loop closes.

Ideas why this is, and what the workaround is?

like image 972
theschmitzer Avatar asked Mar 27 '09 18:03

theschmitzer


2 Answers

For the record, the corrected script looks like this:

setlocal ENABLEDELAYEDEXPANSION

for %%f in (%MYTARGETDIR%\*config.xml) do (

  SET TMPFILE=%%F.tmp

  echo In loop !TMPFILE!
)

echo End loop %TMPFILE%

Thanks chris for your help.

like image 59
theschmitzer Avatar answered Sep 17 '22 11:09

theschmitzer


It because environment variables are substituted when the command is read. For the following command:

for %%f in (%mytargetdir%\*config.xml) do (
    set tmpfile=%%f.tmp
    echo In loop %tmpfile%
)

the entire command (from for to the closing parenthesis) is read and substituted before execution.

You need to use delayed expansion, such as with:

@echo off
    setlocal enableextensions enabledelayedexpansion
    set full=/u01/users/pax
:loop1
    if not "!full:~-1!" == "/" (
        set full2=!full:~-1!!full2!
        set full=!full:~,-1!
        goto :loop1
    )
    echo !full!
    endlocal

When you enable delayed expansion, the "%" markers still act as before but you can use the "!" markers to do the delayed expansion.

like image 23
paxdiablo Avatar answered Sep 20 '22 11:09

paxdiablo