128

when I'm running this script (from a .bat file):

set var1=true
if "%var1%"=="true" (
  set var2=myvalue
  echo %var2%
)

I always get:

ECHO is on.

Meaning the var2 variable was not really set. Can anyone please help me understand why?

aschipfl
  • 33,626
  • 12
  • 54
  • 99
Orad SA
  • 1,885
  • 5
  • 16
  • 16

2 Answers2

246

var2 is set, but the expansion in the line echo %var2% occurs before the block is executed.
At this time var2 is empty.

Therefore the delayedExpansion syntax exists, it uses ! instead of % and it is evaluated at execution time, not parse time.

Please note that in order to use !, the additional statement setlocal EnableDelayedExpansion is needed.

setlocal EnableDelayedExpansion
set var1=true
if "%var1%"=="true" (
  set var2=myvalue
  echo !var2!
)
JRA_TLL
  • 1,186
  • 12
  • 23
jeb
  • 78,592
  • 17
  • 171
  • 225
  • 15
    Thanks you just spared me a huge pain. – Myna Mar 15 '13 at 21:32
  • 2
    Same rule to `&` and `&&`operators. This code `set x=some & set y=%x%thing & echo results %y%` outputs `%x%thing`. – gwarah May 30 '19 at 14:15
  • Sauce: "_With loop commands like FOR, compound or **bracketed** expressions, Delayed Expansion will allow you to always read the current value of the variable. [[1](https://ss64.com/nt/delayedexpansion.html)]_" and, just to show parens _are_ brackets, "_Use parentheses-**brackets**... A GOTO command inside a **bracketed** code block will break the **parentheses** context... [[2](https://ss64.com/nt/syntax-brackets.html)]_" (emph mine). It's really kinda hard imo to google up definitive stuff on `if` & `batch`, though I've googled enough to learn if jeb (no `!`) says it, it's going to be right. – ruffin Jan 12 '23 at 20:32
20

I am a bit late to the party but another way to deal with this condition is to continue process outside if, like this

set var1=true
if "%var1%"=="true" (
    set var2=myvalue
)
echo %var2%

Or/and use goto syntax

set var1=true
if "%var1%"=="true" (
    set var2=myvalue
    goto line10
) else (
    goto line20
)
. . . . .
:line10
echo %var2%
. . . . . 
:line20

This way expansion occurs "in time" and you don't need setlocal EnableDelayedExpansion. Bottom line, if you rethink design of your script you can do it like that

T.S.
  • 18,195
  • 11
  • 58
  • 78
  • 1
    I am unable to access a variable I created inside an if statement. Your first example with var2 does not work. – AntonioCS May 29 '20 at 10:51
  • @AntonioCS interesting... this is exact script that I just tested `echo off set var1=true if "%var1%"=="true" ( set var2=myvalue ) echo %var2% pause`.. and it is working. *"if you will create a variable in the batch file that it can be accessed anywhere in the program."*. https://aticleworld.com/batch-file-variables-and-scope/ – T.S. May 29 '20 at 13:57