Reputation: 11
When delayed variable expansion is enabled, why do we require two escape characters for literal exclamation marks? ^^!
vs ^!
I checked a lot of forums, and there's no explanation for it.
Upvotes: 1
Views: 59
Reputation: 34899
Referring to the thread How does the Windows Command Interpreter (CMD.EXE) parse scripts?, the reason for this is that there are two phases that support ^
-escaping:
^
needs to be escaped as ^^
in order for a literal one to be passed over to further phases.^
that reaches this point can be used to escape special characters, while there are only two such at this point, namely the exclamation mark !
and the caret ^
;So, this results in the following behaviour:
@echo off
setlocal EnableDelayedExpansion
echo ^^! exclamation mark (proper escaping)
echo ^! lost exclamation mark (insufficient escaping, unpaired)
echo ! lost exclamation mark (unpaired)
echo "^!" quoted exclamation mark
echo "!" lost quoted exclamation mark (unpaired)
endlocal
echo/
setlocal DisableDelayedExpansion
echo ^^! exclamation mark (exaggerated escaping)
echo ^! exclamation mark (superfluous escaping)
echo ! exclamation mark (unescaped)
echo "^!" quoted exclamation mark (exaggerated escaping)
echo "!" lost quoted exclamation mark (unescaped)
endlocal
exit /B
Here is the resulting output:
! exclamation mark (proper escaping) lost exclamation mark (insufficient escaping, unpaired) lost exclamation mark (unpaired) "!" quoted exclamation mark "" lost quoted exclamation mark (unpaired) ^! exclamation mark (exaggerated escaping) ! exclamation mark (superfluous escaping) ! exclamation mark (unescaped) "^!" quoted exclamation mark (exaggerated escaping) "!" lost quoted exclamation mark (unescaped)
Upvotes: 4