Buddy Lott said:
Below, I have a script that is uppose to update an enviroment variable
with a
list of files. However FILELIST does not update correctly. Can anyone
tell me
why? This is very similar to some script code that I have not been
able to
get to work.
@setlocal enabledelayedexpansion
@SET FILELIST=NOFILES
@set test=buddy
@set test=buddy1;%test%
@set test=buddy2;%test%
@for %%f in (*.txt) do @(
@echo %FILELIST%
@echo %%f
@set FILELIST=%%f;%FILELIST%;test3
)
echo %FILELIST%
echo %test%
@endlocal
Run the following command at a DOS prompt:
cmd /?
Now look at the /v
n mode for when environment variable delayed
expansion is enabled. See what it says to use for the variable
delimiter character? It isn't the percent sign. If you want to force
the environment variable to get set within the shell for the for-loop
rather than after when the for-loop exits (i.e., immediate expansion
versus delayed expansion) then use the exclamation character to delimit
environment vars within the for-loop's body. Since %f (as %%f is set at
the start of the each loop, you can still use %%f within the body of the
for-loop to get the next value to be used within the for-loop. But the
FILELIST variable is not initialized or changed on each loop so
%FILELIST% refers to the value that was set before the shell for the
for-loop was established (i.e., you will keep using the old value of
FILELIST). So try changing %FILELIST% to !FILELIST!.
That means you will need to use the /v
n switch when loading the
command shell that then runs the .bat or .cmd file. If something like:
set testvar=test
set testvar=!test!string
returns "!test!string" instead of "teststring" then you know that you
need to have that .bat file call itself via:
if not "%testvar%" == "teststring" (
echo <warning messages>
echo Retrying batch file in correct environment
cmd /v
n /c %0 %*
goto BreakOut
)
<here is the script you wanted to run>
:BreakOut
<do cleanup>
Actually I should use "cmd /v
n /c %0 2ndRun %*" and then test if %1 is
"2ndRun" or some other trigger string so that I don't get stuck in a
repeat reexecute looping of the .bat file calling itself in case the
retry didn't work - but, so far, "cmd /v
n" has successfully enabled
the delayed expansion mode but that's because I test on Windows XP. If
I were to distribute this script to others then I would need that check
to ensure they don't get stuck in the .bat file continuously reexecuting
itself should their cmd.exe not support delayed expansion mode (but then
they would have to change cmd.exe to command.com which doesn't have the
/v switch, anyway, and the script would abort out due to not finding the
cmd.exe file).
I haven't used the setlocal command so it might be used to enable
delayed expansion within the .bat file without the need to call itself
again under the correct environment. However, whether you do as I have
or use setlocal, you need to distinguish between when you want delayed
or immediate expansion of environment variables by using a different
delimiter character (i.e., % for delayed and ! for immediate). I use
the .bat file reexecuting itself because I'm not sure under which
versions of Windows the setlocal command is available. I think setlocal
became available as of Windows XP but some of my scripts are ran on
other users' hosts and I won't know if setlocal will be available to
them.