[英]weird handling of double quotes when using cmd /c “echo”
I'm trying to escape some calls in bat file and I found out that I don't understand even on simple example the weird handling of double quotes:我试图逃避 bat 文件中的一些调用,我发现即使在简单的例子中我也不明白双引号的奇怪处理:
Try尝试
cmd /c "echo " "%TEMP%" rem this gives: " "C:\Users\xyz\AppData\Local\Temp
cmd /c "echo" "%TEMP%" rem this gives: The filename, directory name, or volume label syntax is incorrect.
cmd /c "echo beg "TEMP" %TEMP%" rem this gives: beg "TEMP" C:\Users\xyz\AppData\Local\Temp
cmd /c "echo beg ^"TEMP^" %TEMP%" rem this gives: beg "TEMP" C:\Users\xyz\AppData\Local\Temp
cmd /c "echo beg \"TEMP\" %TEMP%" rem this gives: beg \"TEMP\" C:\Users\xyz\AppData\Local\Temp
Just open command prompt (cmd.exe) and paste code.只需打开命令提示符 (cmd.exe) 并粘贴代码。 The results are the same when copy/paste to cmd.exe or running a bat file.复制/粘贴到 cmd.exe 或运行 bat 文件时,结果相同。
What I would expect is that cmd /c "echo beg \"TEMP\" %TEMP%"
should work correcctly.我期望的是cmd /c "echo beg \"TEMP\" %TEMP%"
应该可以正常工作。 At least according to http://daviddeley.com/autohotkey/parameters/parameters.htm#WIN .至少根据http://daviddeley.com/autohotkey/parameters/parameters.htm#WIN 。
But I don't understand output from all the samples.但是我从所有样本中都不了解 output 。 Anybody could explain me that behaviour?任何人都可以向我解释这种行为吗?
Edit :编辑:
The site I'm referencing just explains how arguments are parsed on Windows.我引用的站点只是解释了如何在 Windows 上解析 arguments。 Eg http://daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULES例如http://daviddeley.com/autohotkey/parameters/parameters.htm#WINCRULES
What is my expected output?我的预期 output 是多少? I just want to know how that passing of double quotes work.我只想知道双引号的传递是如何工作的。 Later I'd like to construct command lines like this one:后来我想构建这样的命令行:
pwsh -noprofile -command "produceSomeStringsToFind | % { rg -g testfile* \" $_ some string that ends with quote\\\"" . }"
where rg
is https://github.com/BurntSushi/ripgrep - where the \" $_ some string that ends with quote\\\""
part is regular expression where I need to escape the quotes.其中rg
是https://github.com/BurntSushi/ripgrep - 其中\" $_ some string that ends with quote\\\""
部分结尾是正则表达式,我需要在其中转义引号。
From the help text of cmd /?
来自cmd /?
的帮助文本: :
[...] If /C or /K is specified, then the remainder of the command line after the switch is processed as a command line, where the following logic is used to process quote (") characters: 1. If all of the following conditions are met, then quote characters on the command line are preserved: - no /S switch - exactly two quote characters - no special characters between the two quote characters, where special is one of: &<>()@^| - there are one or more whitespace characters between the two quote characters - the string between the two quote characters is the name of an executable file. 2. Otherwise, old behavior is to see if the first character is a quote character and if so, strip the leading character and remove the last quote character on the command line, preserving any text after the last quote character. [...]
It becomes clear that you are facing the situation explained in section 2.
, because echo
is not an executable file but an internal command.很明显,您正面临第2.
节中解释的情况,因为echo
不是可执行文件而是内部命令。 So if the first character is a "
, it becomes removed and so becomes the last "
, and all the other characters are preserved.因此,如果第一个字符是"
,它将被删除,因此成为最后一个"
,并且所有其他字符都被保留。
Now let us go through your command lines.现在让我们通过您的命令行 go。 So after being parsed and processed by cmd /c
:所以经过cmd /c
解析处理后:
cmd /c "echo " "%TEMP%"
becomes echo " "C:\Users\xyz\AppData\Local\Temp
. cmd /c "echo " "%TEMP%"
变为echo " "C:\Users\xyz\AppData\Local\Temp
。cmd /c "echo" "%TEMP%"
becomes echo" "C:\Users\xyz\AppData\Local\Temp
; cmd /c "echo" "%TEMP%"
变成echo" "C:\Users\xyz\AppData\Local\Temp
; then the command echo"
is tried to be executed, but which is not a valid one, hence it fails.然后命令echo"
被尝试执行,但它不是一个有效的,因此它失败了。cmd /c "echo beg "TEMP" %TEMP%"
becomes echo beg "TEMP" C:\Users\xyz\AppData\Local\Temp
. cmd /c "echo beg "TEMP" %TEMP%"
变为echo beg "TEMP" C:\Users\xyz\AppData\Local\Temp
。cmd /c "echo beg ^"TEMP^" %TEMP%"
becomes echo beg "TEMP" C:\Users\xyz\AppData\Local\Temp
, because escaping with ^
happens even before cmd /c
is executed, so it receives the already escaped literal "
characters. cmd /c "echo beg ^"TEMP^" %TEMP%"
becomes echo beg "TEMP" C:\Users\xyz\AppData\Local\Temp
, because escaping with ^
happens even before cmd /c
is executed, so it receives已经转义的文字"
字符。cmd /c "echo beg \"TEMP\" %TEMP%"
becomes echo beg \"TEMP\" C:\Users\xyz\AppData\Local\Temp
, because the \
is nothing special to cmd
. cmd /c "echo beg \"TEMP\" %TEMP%"
变成echo beg \"TEMP\" C:\Users\xyz\AppData\Local\Temp
,因为\
对于cmd
\ 没什么特别的If you want to output the text "%TEMP%"
(including the quotes), yo could do this:如果你想 output 文本"%TEMP%"
(包括引号),你可以这样做:
rem // This preserves all quotes, because the first character is not such:
cmd /c echo "%TEMP%"
rem // This removes the outer-most pair of quotes, because the first character is such:
cmd /c "echo "%TEMP%""
rem /* This removes the outer-most pair of quotes too, since `cmd /c` receives the already
rem escaped `"`; however, this could be useful to hide these quotes from the hosting
rem `cmd` instance, which avoids issues when `%TEMP%` contains special characters
rem (like `&` or `^`), which you would otherwise have to individually escape: */
cmd /c ^"echo "%TEMP%"^"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.