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

Eoin Campbell

Eoin Campbell
Dad, Husband, Coder, Nerd. I work primarily on the Microsoft .NET & Azure Stack

Qluent

A fluent queue client for interacting with Azure storage queues Continue reading

Migrating from Wordpress to Jekyll

Published on May 08, 2018

I want to be a software architect

Published on January 15, 2018