Using backslash to escape characters in cmd.exe (runas command as example)
I see that the caret is the documented escape character.
But, I have an example showing that for the double quote character, ^
doesn't work and you have to use \
C:\>runas /user:Administrator "cmd /k dir \"%userprofile%\""
Why is that, and where is it documented?
One of the examples in RUNAS /?
shows that syntax. The caret is the escape character for CMD.EXE
but in Windows individual programs are free to implement their own escape characters and globbing.
In cmd, \
does not escape "
. Here's a quick proof and explanation:
Run
echo "" & echo 1
. (&
is a special char in cmd,left & right
means runleft
then runright
.) We can see that bothecho ""
andecho 1
are run successfully.Next, run
echo " & 1234
. We can see that the output is" & 1234
. This is because the opening"
has not been closed, and thus everything after it is interpreted as a string, including the special char&
.-
Run
echo "\" & 1234
.If
\
does escape the following"
, the opening"
will not be closed and the chars& 1234
will be interpreted as part of the string.If
\
fails to escape the following"
, that following"
will close the string and& 1234
will not be interpreted as part of the string.
In the output, we do not see
& 1234
interpreted as part of the string. This proves that\
has failed to escape"
.
So what escapes "
within quotes for argument passing? While ^
will work outside of quotes (easily proven via echo ^" & echo 1
), it does not escape quotes within quotes.
Indeed, how can we get something as simple as echo """
&
echo 1
to work?
The ^
char? ...Nope, echo "^"" & echo 1
outputs "^""
, and not """
.
What about the "
char itself? ...Nope, echo """" & echo 1
outputs """"
, and not """
.
The fact is, there's nothing that will escape "
within quotes for argument passing. You can brood over this for a couple of years and arrive at no solution. This is just some of the inherent limitations of cmd scripting.
However, the good news is that you'll most likely never come across a situation whereby you need to do so. Sure, there's no way to get echo """
&
echo 1
to work, but that's not such a big deal because it's simply a contrived problem which you'll likely never encounter.
For example, consider runas
. It works fine without needing to escape "
within quotes because runas
knew that there's no way to do so and made internal adjustments to work around it. runas
invented its own parsing rules (runas /flag "anything even including quotes"
) and does not interpret cmd arguments the usual way. Official documentation for these special syntax is pretty sparse (or non-existent). Aside from /?
and help
, it's mostly trial-and-error.
The \
sign makes the interpreter interpret the next sign as a character instead of an identifier.
You see it a lot in code as well:
"Hello \"World\""
this is interpreted as
Hello "World"
in your example, in order to pass the arguments to cmd
, it needs to be enclosed in "". But since the arguments to cmd
contains " (and this would end the enclosure) they are appended by \
. If the "" would not have been there, the /k dir \"%userprofile%\"
would have been interpreted as arguments to runas
, not to cmd
.
The reason why they are enclosing the %userprofile% is because this is an environmental variable and will be replaced by text which could contain spaces, which (for the same reason as above) would make the argument to cmd
incorrect.