15

Why does the following Windows Batch File output Foo followedby Bar, rather than Baz?

@echo off
setlocal

set _=Foo
echo %_%
set _=Bar
if 1==1 (
    set _=Baz
    echo %_%
)

The output on my system (Microsoft Windows XP [Version 5.1.2600]) is:

Foo
Bar

If I remove the conditional statement, the expected output of Foo and Baz is observed.

1

3 Answers 3

29

What's happening is that variable substitution is done when a line is read. What you're failing to take into account is the fact that:

if 1==1 (
    set _=Baz
    echo %_%
)

is one "line", despite what you may think. The expansion of "%_%" is done before the set statement.

What you need is delayed expansion. Just about every single one of my command scripts starts with "setlocal enableextensions enabledelayedexpansion" so as to use the full power of cmd.exe.

So my version of the script would be:

@echo off
setlocal enableextensions enabledelayedexpansion

set _=Foo
echo !_!
set _=Bar
if 1==1 (
    set _=Baz
    echo !_!
)

endlocal

This generates the correct "Foo", "Baz" rather than "Foo", "Bar".

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, thanks for the detailed explanation. I think I'm coming up against this exact limitation once again, but in a more restricted environment here: stackoverflow.com/questions/879023/… Unfortunately I don't have the ability to turn on command extensions if I'm using the MSBuild Exec task... hmmm...
4

try this

@echo off
setlocal

set _=Foo
echo %_%
set _=Bar
if "1" NEQ "2" goto end
set _=Baz
echo %_%
:end

Comments

4

The answer to this is the same as the answer to:Weird scope issue in batch file. See there for more details. Basically variable expansion is done at line read time, not at execution time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.