熊奥德
熊奥德

Reputation: 11

Why ^^! and not ^! for literal escapes during delayed variable expansion?

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

Answers (1)

aschipfl
aschipfl

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:

  • Phase 2, special character recognition and tokenisation: an unquoted escape character ^ needs to be escaped as ^^ in order for a literal one to be passed over to further phases.
  • Phase 5, delayed expansion:
    • if enabled, a caret ^ 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 ^;
    • if disabled, the exclamation mark as well as the caret have no special meaning whatsoever;

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

Related Questions