When to use ! In batch
Moderator: DosItHelp
When to use ! In batch
When do you use the ! Sign in batch rather than the % sign for variables?
Re: When to use ! In batch
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.
Re: When to use ! In batch
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:
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.
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
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