Windows – Setting Variables in Windows Batch Scripts

batchscriptingwindows

I need to set some variables based on an argument for a windows batch script.

@echo off       
if [%1]==[] (
    echo "Usage: xxx <AAA|ZZZ>"
) else (
    if [%1]==[AAA] (
        SET SOURCE_DIR=c:\dirA
    ) else if [%1]==[ZZZ] (
        SET SOURCE_DIR=c:\dirZ
    ) 
    echo Source dir is: %SOURCE_DIR%
)

When I call the above script with parameter AAA, I get the output

Source dir is: c:\dirA

after the second call. From then onwards when I alternate between AAA and ZZZ, I get this pattern:

C:\stageing-area>test.bat AAA
Source dir is: c:\dirZ
C:\stageing-area>test.bat ZZZ
Source dir is: c:\dirA
C:\stageing-area>test.bat AAA
Source dir is: c:\dirZ
C:\stageing-area>test.bat ZZZ
Source dir is: c:\dirA

So it looks like I am manipulating a global variable that is available even after the script has finished. This alone doesn't bother me but that the new setting is only available after the script terminates is a problem, as the rest of my script depends on it (obviously).

What is the correct use of local variables in this context? How to explain the weird behaviour of the above "defered state setting"?

Thanks!

Best Answer

Variables in a batch file are by default expanded at the beginning of script execution; you need to use delayed expansion, which is available with the "!" delimiter:

echo Source dir is: !SOURCE_DIR!

This only works if delayed expansion is enabled for the command interpreter, which by default is not; so you need to enable it when starting the interpreter, using CMD.EXE /V.

You can also enable it using this statement in your batch file:

setlocal ENABLEDELAYEDEXPANSION

More info here.