When to use ! In batch

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
batchcc
Posts: 139
Joined: 17 Aug 2015 06:05
Contact:

When to use ! In batch

#1 Post by batchcc » 26 Dec 2015 15:07

When do you use the ! Sign in batch rather than the % sign for variables?

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: When to use ! In batch

#2 Post by Squashman » 26 Dec 2015 17:43

Any time you are changing a variable inside a code block and need to reference that variable inside that code block. A code block means parantheses. So basically when you are using a FOR command or IF command.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: When to use ! In batch

#3 Post by aGerman » 27 Dec 2015 06:14

First of all: The delayed variable expansion has to be set (setlocal EnableDelayedExpansion) in order to be even able to use exclamation marks instead of percent signs.

Why delayed expansion?
Normally variables are expanded to their value before a command line (or an in parentheses enclosed block of command lines) is executed. That means you can't access the new value of a variable if it was changed during the runtime of a command line or block. To avoid this "early" expansion you have to enable the delayed variable expansion and enclose variable names in ! rather than %.
Example:

Code: Select all

@echo off &setlocal EnableDelayedExpansion

set /a "n = 0"
echo Before: %n%

echo In the loop:
for /l %%i in (1 1 3) do (
  set /a "n += 1"
  echo * Iteration #%%i:
  echo     percent signs:     %n%
  echo     exclamation marks: !n!
)

echo After:  %n%
pause

As you can see the body of the FOR loop is enclosed in parentheses and thus it's a block where you need delayed expansion and exclamation marks in order to access the changed values.

One thing you should be aware when using delayed expansion is that it changes the meaning of exclamation marks. That may cause side effects if textual expressions contain exclamation marks. Sometimes you need to switch between enabled and disabled delayed expansion. Rule of thumb:
Assigning a variable is safe with delayed expansion disabled. Working with the assigned variable is safe with delayed expansion enabled.

Code: Select all

@echo off
setlocal DISableDelayedExpansion
set "line=The teacher angry: Shut up! Be quiet & listen to me!"

setlocal ENableDelayedExpansion
echo !line!

pause>nul

Code: Select all

@echo off
setlocal DISableDelayedExpansion
set "line=The teacher angry: Shut up! Be quiet & listen to me!"

echo %line%

pause>nul

Code: Select all

@echo off
setlocal ENableDelayedExpansion
set "line=The teacher angry: Shut up! Be quiet & listen to me!"

echo !line!

pause>nul

The first example shows when and how to switch. And it also shows another advantage of delayed expansion: The output of special characters (the & in this case) works without escaping them.

Regards
aGerman

Post Reply