tags:

views:

55

answers:

2

I have this code:

FOR %%d IN (c d e f g h i j k l m n o p q r s t u v w x y z) do (
     IF NOT EXIST %%d:\ (
      echo Free drive %%d
      set D=%%d:
     )
)

echo d=%D%
echo Using %D% to map remote drive
subst %D% /d
subst %D% \\path_to_drive

and after this I'm using the D variable to map a free drive. The thing is, when I first run this, and try to map the drive, the script thinks that the D variable is undefined, or contains nothing. If I print it's value when the script ends, with:

set D

I see that it found a drive, and it got it's value. When I run the script a second time, it will work as expected. It drives me crazy that batch thinks the variable is undefined, and after the script finishes it's execution it has a value. I'd also like to add that this is the only part where the D variable is used, and that there will ALWAYS be at least one free drive, so, the fact that no drives are available isn't true.

EDIT: I've added the lines that I use to map the drive.

+2  A: 

Depending on where exactly you use the environment variable this may happen. Keep in mind that cmd expands environment variables in the parsing state of a command. And any command that has a parenthesized block is a single, large command itself. So what you posted above is one command and any environment variables are expanded immediately when cmd reads it, instead of when it's executed.

To circumvent this, try putting a

setlocal enabledelayedexpansion enableextensions

at the top of your batch file and use the environment variable with !D! instead of %D%.

Joey
I'm using this variable a couple of lines below to do a `subst`. Will I need to change every variable in the script from `%` to `!` ?
Geo
You can try. It'd help if you posted your complete script in the question or at least the complete part that exhibits the problem. But changing `%` to `!` for the offending variable should be enough.
Joey
By replacing with your code it worked! Thanks!
Geo
I still wonder why it didn't work in the first place. You didn't have yet another block around all this, right?
Joey
This was in an else statement. It probably counts, right?
Geo
Yes, definitely. Every statement "block" within parentheses is a single command which will first be read and parsed and in that stage all environment variables will already be replaced (except when you use `!` and delayed expansion.
Joey
I will keep that in mind for future use. Thank you very much! I don't know how I would have pulled that off without your help :)
Geo
+1  A: 

This works for me, can you see if it works for you on your setup, can you also show us how you reference D?

FOR %%d IN (c d e f g h i j k l m n o p q r s t u v w x y z) do (
        IF NOT EXIST %%d:\ (
                echo Free drive %%d
                set D=%%d:
        )
)
echo %D%
Andy Morris