You are not logged in.

#1 25 Apr 2012 16:08

npocmaka
Member
From: Bulgaria
Registered: 03 Dec 2009
Posts: 446

setting a value to variable inside IF ?

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 mad )?



edit:  there are some hints in SET /?

Last edited by npocmaka (25 Apr 2012 16:16)

Offline

#2 25 Apr 2012 16:58

npocmaka
Member
From: Bulgaria
Registered: 03 Dec 2009
Posts: 446

Re: setting a value to variable inside IF ?

if exist c:\ (
        goto :setValue
) else (
       goto :skipSetValue
)
:setValue
set testvar=b
:skipSetValue

this works.Not sure about nested IFs  smile   .Soon will find out

Offline

#3 26 Apr 2012 02:56

RG
Member
From: Minnesota
Registered: 18 Feb 2010
Posts: 362

Re: setting a value to variable inside IF ?

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

#4 26 Apr 2012 18:03

npocmaka
Member
From: Bulgaria
Registered: 03 Dec 2009
Posts: 446

Re: setting a value to variable inside IF ?

Thanks for the explanation. smile

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

#5 26 Apr 2012 18:47

RG
Member
From: Minnesota
Registered: 18 Feb 2010
Posts: 362

Re: setting a value to variable inside IF ?

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 smile


Windows Shell Scripting and InstallShield

Offline

#6 27 Apr 2012 09:20

jeb
Member
From: Germany
Registered: 19 Nov 2010
Posts: 109

Re: setting a value to variable inside IF ?

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

Board footer

Powered by