| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 |
| Months | ||
|---|---|---|
| Jan | Feb | Mar |
| Apr | May | Jun |
| Jul | Aug | Sep |
| Oct | Nov | Dec |
[02:26] Windows Command Shell Shenanigans
Date: 9/7/05 at 10:26AM
I've been writing a lot of Windows Command Shell scripts recently (can't use WSH because it's not on all the boxes and NT 4 is lowest common denominator) and I ran into a bit of a gotcha with FOR loops. This may not be a gotcha if you are new to programming and actually read the documentation (although in MY defense this doesn't appear to be mentioned in the FOR /? help). So anyway, I expected a FOR loop to behave in a rational Unix shell style fashion. Let me illustrate the problem, here is a functional snippet of code:
1 @ECHO OFF
2 SET THING=w00t
3 FOR %%G in (a b c) DO (SET THING=%THING%,%%G)
4 ECHO %THING%
I'd expect the output to be this:
C:>test_for.cmd
woot,a,b,c
What you actually get is this:
C:>test_for.cmd
woot,c
This is because the command interpreter scans the whole FOR statement in before the iteration begins and resolves any variables that aren't updated by the FOR loop itself so what starts out as:
FOR %%G in (a b c) DO (SET THING=%THING%,%%G)
actually gets run as
FOR %%G in (a b c) DO (SET THING=w00t,%%G)
To get around this you have to use the Windows Command Shell version of procedures. The working version looks like this:
1 @ECHO OFF
2 SET THING=w00t
3 FOR %%G IN (a b c) DO (CALL :GUTS_OF_FOR %%G)
4 ECHO %THING%
5 GOTO EOF
6
7 :GUTS_OF_FOR
8 SET THING=%THING%,%1
9 GOTO :EOF
10
11 :EOF
The command GOTO :EOF DOESN'T actually do what you'd expect, ie GOTO :EOF, it signals to the interpreter that the procedure has completed and that the script should resume at the point where the procedure was called. No, really...