0

I'm trying to understand how the ^ Caret escape works in a Batch CMD. Lets say I type this line in a CMD Window, I would expect it to send the DIR listing to "c:\my text.txt"

CMD.EXE "/C > ^"c:\my text.txt^" DIR C:\*.*"

Instead I get the error:

'txt.txt" DIR *.*"' is not recognized as an internal or external command, 
operable program or batch file.

If I do something as simple as this:

ECHO "^"^""

Expected: """"
Actual  : "^"""

Even if I try double quoting like this:

ECHO " "" "" "

Expected: " " " "
Actual  : " "" "" "

Can someone 'splain how this works and what is a reliable way is to escape double quotes in a command line?

Thanks.

Additional Example:

Why does this work:

cmd.exe "/C sqlcmd.exe -S.\SQLEXPRESS -E -Q"select suser_name()" > "c:\temp\test 1.txt""

but this gives error "The system cannot find the path specified." and does not create the txt file.

cmd.exe "/C "sqlcmd.exe" -S.\SQLEXPRESS -E -Q"select suser_name()" > "c:\temp\test 1.txt""

I know it is not needed in this case, but how would I enclose the command sqlcmd.exe in quotes?

I also tried removing the quotes from the whole line with the same results, i.e.,

cmd.exe /C "sqlcmd.exe" -S.\SQLEXPRESS -E -Q"select suser_name()" > "c:\temp\test 1.txt"

Thanks again.

1 Answer 1

2

Quotes are a state machine within cmd.exe. The first quote turns quoting semantics on, the next quote turns it off, the next back on, etc.

It is possible to escape a quote such that it does not turn quote semantics on.

For example, the following will send a quote character to test.txt

echo ^" >test.txt

Without the escape, the string " >test.txt is simply printed to the screen.

Unfortunately, it is not possible to escape a quote that turns off quote semantics.

For example, suppose you want to print the string "hello world" >"test.txt" to the screen. None of the techniques you tried will work because an internal quote cannot be escaped. The ^" form treats the ^ as a literal, and the output will still be redirected to a file. The "" for properly quotes the >, so there is no redirection, but now you have two quotes instead of one.

You have two options.

1) escape all "poison" characters that are not quoted

echo "hello world" ^>"test.txt"

2) hide the quote literal within a delayed expansion variable

I'm assuming this code is in a batch script.

setlocal enableDelayedExpansion
set "quote=""
echo "hello world!quote! >!quote!test.txt"

Note that using this technique can become tricky if dealing with FOR /F ... IN('command') or CMD /C because delayed expansion will probably be off within the new CMD.EXE context.


Here is a way to do your original command

cmd /c dir c:\*.* ^>"c:\my text.txt"

Note that the entire command string after /c does not have to be enclosed within quotes. In this case, it is easier if it is not.


I believe your new command at the end can be written as follows:

cmd.exe /C ""sqlcmd.exe" -S.\SQLEXPRESS -E -Q"select suser_name()" > "c:\temp\test 1.txt""

If used within a parenthesized block, then the right paren will need to be escaped.

(
  cmd.exe /C ""sqlcmd.exe" -S.\SQLEXPRESS -E -Q"select suser_name(^)" > "c:\temp\test 1.txt""
)
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the reply. I added an Additional Example above as the comments allow limited formatting. I tried using your suggestions but still no luck.
@Neilw - I tested the code in my answer, and they all work (I had forgotten to include the setlocal enableDelayedExpansion - edit has been made). I haven't had a chance to work on the more complicated command in your edited answer.
@Neilw - OK, I think I have a solution for your updated question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.