Difference between %variable% and !variable! in batch file

If you have delayed expansion enabled and want to output an exclamation mark, you need to escape it.

Escaping of exclamation marks needs none, one or two carets, depending on the placement.

@echo off
REM No escaping required, if delayed expansion is disabled
set test1=Test1!

setlocal EnableDelayedExpansion
REM One caret required
REM Delayed expansion uses carets independent of quotes to escape the exclamation mark
set "test2=Test2^!"

REM Two carets required
REM The first caret escapes the second caret in phase2 of the parser
REM Later in the delayed expansion phase, the remaining caret escapes the exclamation mark
set test3=Test3^^!


echo !test1!
echo !test2!
echo !test3!

The difference between !var! and %var% in blocks is explained at DOS batch: Why are my set commands resulting in nothing getting stored?

An explanation of the batch parser can be found at How does the Windows Command Interpreter (CMD.EXE) parse scripts?

Leave a Comment