Logical AND (&&) doesn't work in IF

June 22, 2010 at 06:55:56
Specs: Windows XP
I've been struggling with this all day! This works fine:

set f=0
find "IC5701" C:\temp\192.168.127.1.xml && set f=1
echo %f%

So why doesn't this work:

set f=0
if exist C:\Custer\temp\192.168.127.1.xml (
	find "IC5701" C:\temp\192.168.127.1.xml && set f=1
	echo %f%
)


See More: Logical AND (&&) doesnt work in IF

Report •

#1
June 22, 2010 at 08:25:24
Clarification request:
What get displayed? 0? An error?

Insomniac at large


Report •

#2
June 22, 2010 at 09:17:31
Sorry. Yes, it displays 0. I have figured this out though, and for the number of times I've seen references to this pitfall, I should have guess it sooner. This works:

setlocal EnableDelayedExpansion
set f=0
if exist C:\temp\192.168.127.1.xml (
	find "IC5701" C:\temp\192.168.127.1.xml && set f=1
	echo !f!
)


Report •

#3
June 22, 2010 at 13:36:54
Required reading:
set /?
 . . . . . . . . . . . . . . . . . . . .
Delayed environment variable expansion is useful for getting around
the limitations of the current expansion which happens when a line
of text is read, not when it is executed.  The following example
demonstrates the problem with immediate variable expansion:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "%VAR%" == "after" @echo If you see this, it worked
    )

would never display the message, since the %VAR% in BOTH IF statements
is substituted when the first IF statement is read, since it logically
includes the body of the IF, which is a compound statement.  So the
IF inside the compound statement is really comparing "before" with
"after" which will never be equal.  Similarly, the following example
will not work as expected:

    set LIST=
    for %i in (*) do set LIST=%LIST% %i
    echo %LIST%

in that it will NOT build up a list of files in the current directory,
but instead will just set the LIST variable to the last file found.
Again, this is because the %LIST% is expanded just once when the
FOR statement is read, and at that time the LIST variable is empty.
So the actual FOR loop we are executing is:

    for %i in (*) do set LIST= %i

which just keeps setting LIST to the last file found.

Delayed environment variable expansion allows you to use a different
character (the exclamation mark) to expand environment variables at
execution time.  If delayed variable expansion is enabled, the above
examples could be written as follows to work as intended:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "!VAR!" == "after" @echo If you see this, it worked
    )

    set LIST=
    for %i in (*) do set LIST=!LIST! %i
    echo %LIST%

And also:

setlocal /?
 . . . . . . . . . . . . . . . . . . . . . . . . 
SETLOCAL batch command now accepts optional arguments:
        ENABLEDELAYEDEXPANSION / DISABLEDELAYEDEXPANSION
            enable or disable delayed environment variable
            expansion.  See SET /? for details.


Report •
Related Solutions


Ask Question