tags:

views:

1135

answers:

2

What will the following DOS .bat file code segment display? Why? (i.e. why doesn't it behave as you might first think)?

set VAR=before

if "%VAR%" == "before" (

set VAR=after;

echo %VAR%

)

[I do know the answer to this, but figured this valuable enough to post]

+3  A: 

Obviously, you'd think the output would be "after", given that we reset the env variable inside the loop.

But the output will actually be "before". The reason is that variable substitution is done in .bat files by the interpreter when a command is read, rather than when it's executed. So, for the compound statement, the variables in the body are evaluated when the if statement is first encountered.

You can make this work by using delayed environment variable expansion (need to enable it). If it's enabled, you can then do:

set VAR=before

if "%VAR%" == "before" (

set VAR=after;

echo !VAR!

)

You can enable delayed environment variable expansion using the /v option when starting cmd.exe.

[Backstory--many of us still use legacy .bat files to drive things like make procedures, etc. Obviously there are better scripting tools, but not always an option to use them. I ran into this issue a while back and recently found two other people who had pulled their hair out over the same thing. So it's useful to understand how the interpreter does variable substitution].

Sean Sexton
A: 

The substitution for %VAR% occurs before the execution of the command. Even though there are several commands spread over several lines, the grouping of them in parens (...) causes the cmd.exe parser to read the whole thing in as a single command. So what gets executed looks like:

set VAR=before

if "before" == "before" (

set VAR=after;

echo before

)

to the interpreter.

This is one of the many things that make batch file processing rather painful hen trying to do anything more than simple stuff.

Michael Burr