Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Command line SETLOCAL?

May
12,845
164
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
 
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
 
Yes, in my example it seems that the last of the multiple commands is being expanded/escaped early.
 
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
 
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
 
IMHO, that shouldn't be necessary. But, alas, a workaround makes it less likely to be fixed.
 
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.
 
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?
 
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.
 
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)!
 
Maybe renaming the option to something like "Emulate CMD.EXE even if strange, illogical or undocumented" would make more people who need it keep it set. Take out the word bug even though technically those things are.
 

Similar threads

Back
Top