Reputation: 37
so i have in a batch-file some vars stored from a text file
(
set /p var1=
set /p var2=
set /p var3=
)<oi.txt
and they represent an if statement.
if i were to run %var1% it would run the if statement, however when i run
for /l %%i in (1,1,3) do !var%%i!
(in setlocal enabledelayedexpansion) it runs the if, however it returns
`if` is not recognized as an internal or external command
`if` is not recognized as an internal or external command
`if` is not recognized as an internal or external command
is it a microsoft oversight? or maybe something that fixes another bug at the price of not having this option?
*edit this has nothing to do with the for command, using !var%number%! with var1 having the if statement inside, returns the same problem. (also, im 100% sure the if statement inside the var is correct, why wouldnt it be recognized even if it was wrong?)
Upvotes: 4
Views: 91
Reputation: 130819
When you execute commands that are stored within an environment variable, that is frequently called a macro. Very complicated macros can be created and executed by using %macro%
. But execution of !macro!
via delayed expansion is severely crippled - there are many restrictions.
The cmd.exe command (and batch) parser is a complicated beast. I'm not aware of any official documentation that would explain the behavior.
But there are a set of parsing phase rules developed by jeb that help explain why delayed expansion macro execution does not work with IF or FOR statements.
Both IF and FOR require special parsing that occurs in phase 2. But delayed expansion does not occur until phase 5. So the required IF and FOR parsing never occurs when you try to execute commands via delayed expansion.
There is no work around. If you want to include FOR or IF within an environment variable "macro", then you must execute the macro with normal %macro%
expansion.
The explanation is basically the same as to why you cannot use delayed expansion for FOR or IF options or flags.
Here is an IF example:
@echo off
setlocal enableDelayedExpansion
set "ifFlag=/I"
:: This works
if %ifFlag% a==A echo match
:: This does not work
if !ifFlag! a==A echo match
And here is a FOR example:
@echo off
setlocal enableDelayedExpansion
set "forOptions=delims=: tokens=1,2"
:: This works
for /f "%forOptions%" %%A in ("1:2") do echo A=%%A B=%%B
:: This does NOT works
for /f "!forOptions!" %%A in ("1:2") do echo A=%%A B=%%B
Upvotes: 3