Welcome

My name is Jason and I am a software developer in the Bay Area. For fun I like to hike, run, shoot some photos, and take advantage of the many other activities California state has to offer. To the right you will see my resume.

Recent Books
  • Head First Design Patterns
    Head First Design Patterns
    by Elisabeth Freeman, Eric Freeman, Bert Bates, Kathy Sierra, Elisabeth Robson
« Interview question: Palindrome detecting algorithm | Main
Saturday
Dec192009

Variable Expansion Within a DOS FOR Loop

Ah, the DOS FOR loop. Had I known about you earlier in life, I would probably have a day or two back. But atlas, it wasn't until recently that we met.

My first tech blog post and I'm talking about a FOR loop in DOS? Well, I figured I should start at the beginning, and for me, that's DOS.

In my current contract, I do a lot of automation in DOS. And any kind of automation is made easier with loops. Enter the FOR command. I have to admit that I didn’t know anything about the FOR command under DOS before I started this job and had to analyze someone else’s batch files. But now that I have, I’m a better scripter for knowing it.

One of the more troublesome things that I’ve dealt with is trying to set environment variables and using them all within the FOR loop. It just doesn’t work. But if you stop to think about it, it makes sense as to why it doesn’t work. Look at the example below.

Script

SET check=0
FOR %%A IN (1 2) DO (
   SET check=%%A
   ECHO Mic check %check%.
)

Output

Mic check 0.
Mic check 0.

Because all of the environment variables within the DO () are expanded only when the FOR command is reached, not for every iteration of the loop, their values are static. So in this example when the FOR command is reached, the expansion of check to its current value of 0 takes place and then the looping begins. It would look something this.

SET check=0
FOR %%A IN (1 2) DO (
   SET check=%A
   ECHO Mic check 0.
)

Note how check is expanded to 0 inside the DO ().

So, how do you deal with this limitation? There are 2 ways. The first is by using the CALL command to move the logic out of the DO () and to a different part of your script. Below is a modified version of the script that behaves in the wanted manner.

Script

SET check=0
FOR %%A IN (1 2) DO (
   CALL :MicCheck %%A
)
GOTO :eof

:MicCheck
SET check=%1
ECHO Mic check %check%.
GOTO :eof

Output

Mic check 1.
Mic check 2.

The second way of handling this is by turning on delayed variable expansion. I don’t like this method as much because unless you have it enabled by default, which it’s not as of the time of this posting, scripts don’t work out-the-door. For them to work on first run, you have to play with the SETLOCAL and ENDLOCAL commands inside your batch file. I’ve run into odd scope behaviors in the past doing this, so I prefer the CALL method shown above.

Script

SET check=0
SETLOCAL ENABLEDELAYEDEXPANSION

FOR %%A IN (1 2) DO (
   SET check=%%A
   ECHO Mic check %check%.
)

ENDLOCAL

Output

Mic check 1.
Mic check 2.

Now, this is a simple example, but I’m sure you can see how you can expand this to do what you’d like.

Happy scripting!

Reader Comments (1)

Thanks.
You helped me alot to understand more about batch scripting.

greetz from bavaria

November 4, 2010 | Unregistered CommenterDennis

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>