Command line SETLOCAL?

#1
Using SETLOCAL on the command line was mentioned in another thread. I had never used it so I played with it a bit. I don't quite understand what's happening below. In the first example, second ECHO, why is %zz still 2? In the second example why isn't the same thing echoed twice?

Code:
v:\> setlocal & set zz=2 & echo %zz & endlocal & set zz & echo %zz
2
TCC: Not in environment "zz*"
2

v:\> setlocal & set zz=2 & echo %%zz & endlocal & set zz & echo %%zz
%zz
TCC: Not in environment "zz*"
ECHO is OFF
 
Feb 26, 2013
100
0
#2
Using SETLOCAL on the command line was mentioned in another thread. I had never used it so I played with it a bit. I don't quite understand what's happening below. In the first example, second ECHO, why is %zz still 2? In the second example why isn't the same thing echoed twice?

Code:
v:\> setlocal & set zz=2 & echo %zz & endlocal & set zz & echo %zz
2
TCC: Not in environment "zz*"
2

v:\> setlocal & set zz=2 & echo %%zz & endlocal & set zz & echo %%zz
%zz
TCC: Not in environment "zz*"
ECHO is OFF
I can't explain it, but it seems it's something to do with multiple commands on one line. If the commands are entered one at a time it works as I would expect:

Code:
d:\>set zz
TCC: Not in environment "zz*"

d:\>setlocal

d:\>set zz=2

d:\>echo %zz
2

d:\>set zz
2

d:\>endlocal

d:\>set zz
TCC: Not in environment "zz*"

d:\>echo %zz
ECHO is OFF
 
Feb 26, 2013
100
0
#4
Yes, in my example it seems that the last of the multiple commands is being expanded/escaped early.
Further observations, it seems to be all expansions after the endlocal , not just the last command on the line:

Code:
d:\>setlocal & set zz=2 & echo %zz & endlocal & set zz & echo %zz & set zz & echo %zz
2
TCC: Not in environment "zz*"
2
TCC: Not in environment "zz*"
2
and the same thing happens if you nurdle more than one variable within the setlocal/endlocal pair:

Code:
d:\>setlocal & set zz=2 & set yy=3 & echo %zz & echo %yy & endlocal & set zz & set yy & echo %zz & & echo %yy
2
3
TCC: Not in environment "zz*"
TCC: Not in environment "yy*"
2
3
 
Feb 26, 2013
100
0
#5
One more thing I've spotted, if you disable variable expansion before the endlocal it stops the expansion to the end of the line, but the endlocal still appears to reset the setdos /x3 state correctly

Code:
d:\>setlocal & set zz=2 & echo %zz & setdos /x-3 & endlocal & set zz & echo %zz
2
TCC: Not in environment "zz*"
ECHO is OFF
 
Feb 26, 2013
100
0
#7
IMHO, that shouldn't be necessary. But, alas, a workaround makes it less likely to be fixed.
I absolutely agree Vince, it shouldn’t be necessary, the parser is clearly not handling variable expansion correctly when there’s an endlocal in a situation with multiple commands on one line. I hadn’t intended my observation to be seen as a workaround, more as evidence of the problem and perhaps helping Rex identify what’s going on.
 

rconn

Administrator
Staff member
May 14, 2008
10,532
94
#8
Using SETLOCAL on the command line was mentioned in another thread. I had never used it so I played with it a bit. I don't quite understand what's happening below. In the first example, second ECHO, why is %zz still 2? In the second example why isn't the same thing echoed twice?

Code:
v:\> setlocal & set zz=2 & echo %zz & endlocal & set zz & echo %zz
2
TCC: Not in environment "zz*"
2

v:\> setlocal & set zz=2 & echo %%zz & endlocal & set zz & echo %%zz
%zz
TCC: Not in environment "zz*"
ECHO is OFF
WAD. ENDLOCAL will expand the entire line, regardless of any command separators.

If this doesn't make any sense, it's because it's for compatibility with CMD. No, I don't know why CMD does it, and no, it isn't documented, but there are a number of batch files out there that assume this (somewhat bizarre) behavior.

Since you didn't have any apparent reason for using this syntax, I assume that this was an example and not the real purpose. Exactly what do you want to do with the ENDLOCAL?
 
Feb 26, 2013
100
0
#9
Since you didn't have any apparent reason for using this syntax, I assume that this was an example and not the real purpose. Exactly what do you want to do with the ENDLOCAL?
In my case I don’t have a use case for a command line SETLOCAL/ENDLOCAL at all; my interest was piqued by Vince’s observation of its behaviour.

If this doesn't make any sense, it's because it's for compatibility with CMD. No, I don't know why CMD does it, and no, it isn't documented, but there are a number of batch files out there that assume this (somewhat bizarre) behavior.
In that case I’d suggest it’s a candidate for inclusion with the other slightly warped behaviours controlled by the “Duplicate CMD.EXE bugs” directive, then it could behave sensibly for those only using TCC.
 

rconn

Administrator
Staff member
May 14, 2008
10,532
94
#10
In that case I’d suggest it’s a candidate for inclusion with the other slightly warped behaviours controlled by the “Duplicate CMD.EXE bugs” directive, then it could behave sensibly for those only using TCC.
That would be reasonable if anybody actually had an issue with the current behavior -- but it seems that the complaints / bug reports are based solely on an imaginary & non-useful syntax.

I have enough problems with the IF behavior; a lot of people turn off the "Duplicate CMD.EXE bugs" option and then file bug reports that their CMD batch files no longer work. And the IF behavior is at least comprehensible (if not sensible)!