I have a script that creates new batch files inside a for
loop.
This is the code:
@echo on
SET "files=2"
SET "desired_count=2"
FOR /L %%G IN (1,1,%files%) DO (
IF %%G LSS 10 (
(
echo echo on
echo set "counter=0"
echo set desired_count=%desired_count%
echo.
echo :startpoint
echo set /a "counter+=1"
echo IF "!counter!" LSS %desired_count% goto startpoint
) >> file_0%%G.bat
)
)
I am completely lost when trying to pass variables inside for
and if
statements. The solution presented in some other forum posts suggests using set local EnableDelayedExpansion
, but I have not managed to get that to work for me so far.
In the created .bat files I would like the script to loop until the desired_count
is met.
The file_01.bat
that is created is below.
echo on
set "counter=0"
set desired_count=2
:startpoint
set /a "counter+=1"
IF "!counter!" LSS 2 goto startpoint
When that is submitted it infinitely loops around this line:
IF "!counter!" LSS 2 goto startpoint
Playing around with different combinations of set local EnableDelayedExpansion
, changed what happened, but I couldn't get it correctly count in the loop.
@echo on
SETLOCAL
SET "files=2"
SET "desired_count=2"
FOR /L %%G IN (1,1,%files%) DO (
IF %%G LSS 10 (
(
echo echo on
ECHO SETLOCAL ENABLEDELAYEDEXPANSION
echo set "counter=0"
echo set desired_count=%desired_count%
echo.
echo :startpoint
echo set /a "counter+=1"
echo IF !counter! LSS %desired_count% goto startpoint
) >> file_0%%G.bat
)
)
[untested]
Changes : Inserted setlocal
after @echo on
. This establishes a local environment
which means that any changes made to the environment variables while running this code are discarded when the batch ends so the environment remains clean - not altered by successively running batch files.
Inserted ECHO SETLOCAL ENABLEDELAYEDEXPANSION
to follow the echo on
in the generated file. The full command is SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
, but by default, ENABLEEXTENSIONS
is enabled and ENABLEDELAYEDEXPANSION
disabled, so this shorter form is usually adequate. This instruction causes cmd
to interpret !var!
as the run-time value of var
(ie. as it might change within a loop.)
Removed quotes from IF "!counter!" LS…
As your original code would be interpreted, the statement would be resolved to "if "!counter!"
LSS 2
…" where "!counter!"
is precisely that - the literal string "!counter!"
. Since "!counter!"
is less than 2
, you get an infinite loop.
The setlocal enabledelayedexpansion
would change this interpretation to "if "thecurrentvalueofcounter"
LSS 2
…" - but this is still incorrect as if
syntax compares the expressions on both sides of the comparator (LSS
) literally, so you might get "if "2"
LSS 2
…" for instance. The string "2"
is always less than 2
. To accomplish what you need to do, you need to compare the two values, ie !counter!
LSS 2
.
Note that IF "!counter!" LSS "2" g…
may appear to work, but in this case, the comparison is performed as strings, hence "2" LSS "2"
,"3" LSS "2"
, etc. Perfect... except "12" LSS "2"
is true because the comparison is performed character-by-character and 1
is less than 2
.
However ------
In the generated batch, you don't need to use the delayedexpansion
syntax as counter
is not contained in a code block
(parenthesised sequence of commands)
Hence, you could use
echo IF %%counter%% LSS %desired_count% goto startpoint
which would generate
IF %counter% LSS 2 goto startpoint
%
"escapes" (turns off) the special meaning of %
, and since the generated IF %counter%…
code is not in a code block, there is no need for the delayedexpansion
syntax here. This means that the delayedexpansion
keyword is also not required.See Stephan's DELAYEDEXPANSION link for more info