Search code examples
windowsif-statementbatch-filecmderrorlevel

Batch file: Two consecutive IFs


I'm trying to understand the syntax of IF in batch files.

Given this code (works):

CHOICE /C YN /M "Do it?"
IF ERRORLEVEL == 2 GOTO skip
IF ERRORLEVEL == 1 GOTO doIt
GOTO end

:doIt
echo Do it!
GOTO end

:skip
echo Abort!
GOTO end

:end

Why can't I change the order of the two IF's? If I would write IF ERRORLEVEL == 1 GOTO doIt at first, I get wrong behavior. Now Do it gets executed every time, regardless of the input.


Solution

  • The if command supports a few special (case-insensitive) keywords:

    • exist (to check for file existence)
    • defined (to check for environment variable)
    • ErrorLevel (to check for the last error)
    • CmdExtVersion (to check for command extensions)

    If any of those is encountered immediately behind if, if /I, if not or if /I not, special comparison modes are entered. If none of these keywords is present, a normal comparison of two values is expected (using the comparison operator == to force string comparison, or using one of equ, neq, gtr, geq, lss, leq for trying to interpret both values as integers and comparing them as such, or, if not possible, comparing them as strings).

    Since you have stated the keyword errorlevel immediately following the if command, a numeric value is expected. The equal-to sign is no longer treated particularly, rather is it just regarded as a standard token delimiter just like a SPACE, according to this section1, and multiple consecutive delimiters are collapsed into one.

    Therefore, your command line if errorlevel == # is equivalent to if errorlevel #, meaning if ErrorLevel is greater than or equal to #. For that reason, you cannot exchange the two if command lines, because an errorLevel value of 2 would also fulfil said condition against the value 1.


    1) Actually, the vertical tabulator (code 0x0B) and the non-break space (code 0xFF) are missing in this list.