You are not logged in.
another strange behavior of IF:
result of this :
@echo off
call set testvar=a
if exist c:\ (
set testvar=b
echo %testvar% -- first echo
)
echo %testvar% -- second echo
is:
a -- first echo
b -- second echo
When I expect to be:
b -- first echo
b -- second echo
Any idea why the set is valid after IF command is finished? (there is no such problem with FOR) (enabledelayedexpansion does not help much because I can change the variable only inside setlocal block(?))
Any idea how this can be worked-around (may be with GOTOs inside IF )?
edit: there are some hints in SET /?
Last edited by npocmaka (25 Apr 2012 16:16)
Offline
if exist c:\ (
goto :setValue
) else (
goto :skipSetValue
)
:setValue
set testvar=b
:skipSetValue
this works.Not sure about nested IFs .Soon will find out
Offline
Here's one way to do it:
@echo off
setlocal enabledelayedexpansion
set testvar=a
if exist c:\ (
set testvar=b
echo !testvar! -- first echo
)
echo %testvar% -- second echo
endlocal
By way of explanation... Note that I enabled delayed expansion and used ! instead of % to expand the variable at run-time instead of at load-time. I think you are looking at the code and only considering the run-time behavior.
Consider that we are dealing with two behaviors: 1) Load-time, and 2) Run-Time.
Most people are aware that a line is loaded at a time.... but really the entire IF construct (everything between the parens) is loaded as one line. So in your example, the value %testvar% in the first echo statement is expanded when the IF construct is loaded.
Always remember... two behaviors. 1) Load-time, and 2) Run-Time.
Last edited by RG (26 Apr 2012 02:58)
Windows Shell Scripting and InstallShield
Offline
Thanks for the explanation.
The problem with enabledelayedexpansion is that the set value will be usable only within setlocal->endlocal block.
And IF became useless when I intend to use it in a called bat or subroutine.
In this case I can't think out another way except goto and labels outside the if.
Last edited by npocmaka (26 Apr 2012 22:08)
Offline
Not exactly true. As usual... there is a way!
You can use a technique called "tunneling".
Go to this post and scroll down to my 3rd post.
http://ss64.org/viewtopic.php?id=985
Always remember... two behaviors. 1) Load-time, and 2) Run-Time
Windows Shell Scripting and InstallShield
Offline
RG uses here the standard technic to return values behind a endlocal-barrier.
setlocal EnableDelayedExpansion
set var=something
(
endlocal
set "result=%var%"
)
This works quite good, until you have quotes, carets and other special characters in your variables.
But then you can use the FOR-technic to return the value
setlocal EnableDelayedExpansion
set var=something
for /f "delims=" %%a ("!var!") do
(
endlocal
set "result=%%~a"
)
The For-technic works good until you return into an other EnabledDelayed context and your content contains exclamation marks,
then you need a much more complex solution.
jeb
Offline