if-statementbatch-filecmderrorlevel

ERRORLEVEL in if statement not works correctly


In this batch file ERRORLEVEL is displayed correctly (First option returns 1 and the second returns 2):

@echo off
choice /C YN /M "Yes or No"
echo The actual errorlevel is: %ERRORLEVEL%
pause
exit

But when i try with if statements something happens:

@echo off
choice /C YN /M "Yes or No"
if (%ERRORLEVEL% == 1) (echo You chose "Yes")
if (%ERRORLEVEL% == 2) (echo You chose "No")
pause
exit

Here no message is displayed... Any help? Am i doing something wrong?


Solution

  • Remove parenthesis:

    if %ERRORLEVEL% == 1 echo You chose "Yes"
    if %ERRORLEVEL% == 2 echo You chose "No"
    

    Explanation

    Unlike langauages like C, Javascript or Python, parenthesis in batch scripts denote blocks of code like { and }

    So putting them around == checks is not needed and should not be used. If you want more complex expressions, you would instead probably have to split it into several if commands as outlined in this article about if

    EDIT:

    As noticed by Stephan :

    In this case the mistake is caused by command processor understanding ( and ) as a part of comparison strings, rather than as special characters, and so interpreting your statement as comparison between strings (%ERRORLEVEL% and 1) so string "(1" is compared to "1)" - they do not match so expression is false, but error is not generated since this is technically valid syntax (even though it does not do what you wanted)

    You could write "%ERRORLEVEL%" == "1" to disambiguate your intentions, but really parenthesis should just not be used here

    Although parenthesis around echo should work in this particular case on modern Windows...

    if %ERRORLEVEL% == 1 (
        echo You chose "Yes"
    )
    

    Here is a more thorough explanation of parenthesis in batch scripts.

    Additional note on exit:

    You do not need exit at the end of the script unless you want the whole batch execution to be aborted.

    This is relevant if one batch script is called from another, or in a subroutine.

    If you want to end execution of your *.bat file or subroutine use goto :eof (note the colon) - this is similar to placing a label at the very end of the script and jumping to it with goto.

    However, exit /b allows to exit a script and set ERRORLEVEL code to a specified value. This only returns from running subroutine or batch-script and not terminates cmd.exe as plain exit does.

    More info on exit can be found here