Here's the example:
@echo off
:: check syntax ignores "^<delimiter>something" right after check expression
if defined path^ blah echo #
if exist c:\^ blah echo #
if errorlevel 0^ blah echo #
:: but in comparison operations escaping works well
if 1^ blah==1^ blah echo #
Why?
I don't know.
But It seems that the tokenizer executes two times in this cases.
Here is an example to show that the tokenizer is independent of the interim output of
ECHO ON
Both lines are shown as
if !var! == hello you echo true
but only the first executes theecho true
, as therehello you
is one token but not in the second sample.But as dbenham explains, the
IF DEFINED
and theIf EXIST
seems to tokenize it first as expected, as the second word will not be used as a command, but it's completly dropped.The interessting effect is that a FOR parameter and delayed expansion aren't affected, although these phases are following directly the echo phase.
So I assume, that there is used another tokenizer by
IF defined
andIF EXIST
in contrast toIF .. <compare>
.With
ECHO ON
(as JosefZ mentioned) you can see the differences.Output
In the first case the
hello you
is complete, but in the second sample theyou
was dropped.Because that is how it works ;-)
In my opinion it is a design flaw with the IF command. The IF command has complicated (multiple phase) parsing rules, and I think MicroSoft dropped the ball a bit.
Escape does not work with IF EXIST or IF DEFINED. The first parsing pass properly identifies the condition and command, but the actual comparison stops at the first white space.
Quotes work with IF EXIST. But quotes do not help with IF DEFINED because they are considered to be part of the variable name.
The only way to get it to work properly in all cases is to use a FOR variable or delayed expansion:
--OUTPUT--