Unexpected Variable Behaviour in DOS Batch and Delayed Expansion

What would you expect the following piece of Code to print. if the directory ‘A’ doesn’t exist

@ECHO OFF
IF '1'=='1' (
        CD a
        ECHO %ERRORLEVEL%
)

CD a
ECHO %ERRORLEVEL%

Not very intuitive right?

This is because the DOS batch processor treats the whole if statement as one command, expanding the variables only once, before it executes the conditional block. So you end up with %ERRORLEVEL% being expanded to its value, which is 0, before you start the block, You can get around this by enabling Delayed Expansion. As the name suggests this forces the the Batch Processor to only expand variables once required to do so in the middle of execution.
To enable this behavior you need to do 2 things.
  1. SET ENABLEDELAYEDEXPANSION at the top of your script.
  2. Replace % delimited variables with an Exclamation. i.e. %ERRORLEVEL% becomes !ERRORLEVEL!

Now our script looks like this, and behaves as expected.

Working Script

@ECHO OFF
REM Enable Delayed Expansion
setlocal enabledelayedexpansion
IF '1'=='1' (
        CD a
        REM Use Exclamations instead of percentages
        ECHO !ERRORLEVEL!
)

CD a
ECHO %ERRORLEVEL%
For when powershell just isn’t retro enough 😉
~Eoin C

Leave a Reply

Your email address will not be published. Required fields are marked *