在参数中转义双引号
在 Unix 中,我可以运行 myscript '"test"'
并且得到 "test"
。
在 Windows cmd
中,我得到 'test'
。
如何传递双引号作为参数?我想知道如何从 cmd
窗口手动执行此操作,这样我就不必编写程序来测试我的程序。
In Unix I could run myscript '"test"'
and I would get "test"
.
In Windows cmd
I get 'test'
.
How can I pass double-quotes as a parameter? I would like to know how to do this manually from a cmd
window so I don't have to write a program to test my program.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我发现在某些地方使用的另一种转义引号的方法(尽管可能不是首选)是使用多个双引号。为了使其他人的代码清晰易读,我将进行解释。
以下是一组基本规则:
program param1 param2 param 3
会将四个参数传递给program.exe< /code>:
param1
、param2
、param
和<代码>3。程序一二“三及更多”
将向program.exe
传递三个参数:一个
、两个
和三个及更多
。Now to explain some of the confusion:
hello"to the another"world
充当一个参数:helloto the anotherworld< /代码>。
Note: The previous rule does NOT imply that two double-quoted groups can appear directly adjacent to one another.
"Tim said, ""Hi!"""
将充当一个参数:Tim said, "Hi!"
因此,存在三种不同类型的双引号: 、结束引号以及充当纯文本。
这是最后令人困惑的一行的细分:
因此,文本有效地连接了四组字符(但是其中一组没有任何字符):
蒂姆说,
是第一个,包裹起来以逃避空格“Hi!
是第二个,未换行(没有空格)是第三个,双引号组不包含任何内容
"
是第四个,展开的闭引号。如您所见,不包含任何内容的双引号组仍然是必要的,因为如果没有它,下面的双引号将打开一个双引号组 将打印
Tim said to his
从这里,应该可以看出,因此,在引号内部和外部,三个双引号充当纯文本未转义双引号:
, "What's到过最近发生了什么?” 正如预期的那样。因此,三个引号始终可以可靠地用作转义。
但是,在理解它时,您可能会注意到末尾的四个引号可以减少到仅仅两个因为从技术上讲,它添加了另一个不必要的空双引号组,
以下是一些将其关闭的示例:
最后一点:我没有从任何教程中阅读任何内容 - 我通过实验想出了所有这些内容。尽管如此,上述所有示例的内部解释可能并不正确。正如给定的,从而验证(但不是证明)我的理论。
我在 Windows 7 64 位上仅使用带有参数传递的 *.exe 调用(不是 *.bat,但我认为它的工作原理相同)进行了测试。
Another way to escape quotes (though probably not preferable), which I've found used in certain places is to use multiple double-quotes. For the purpose of making other people's code legible, I'll explain.
Here's a set of basic rules:
program param1 param2 param 3
will pass four parameters toprogram.exe
:param1
,param2
,param
, and3
.program one two "three and more"
will pass three parameters toprogram.exe
:one
,two
, andthree and more
.Now to explain some of the confusion:
hello"to the entire"world
acts as one parameter:helloto the entireworld
.Note: The previous rule does NOT imply that two double-quoted groups can appear directly adjacent to one another.
"Tim says, ""Hi!"""
will act as one parameter:Tim says, "Hi!"
Thus there are three different types of double-quotes: quotes that open, quotes that close, and quotes that act as plain-text.
Here's the breakdown of that last confusing line:
Thus, the text effectively joins four groups of characters (one with nothing, however):
Tim says,
is the first, wrapped to escape the spaces"Hi!
is the second, not wrapped (there are no spaces)is the third, a double-quote group wrapping nothing
"
is the fourth, the unwrapped close quote.As you can see, the double-quote group wrapping nothing is still necessary since, without it, the following double-quote would open up a double-quoted group instead of acting as plain-text.
From this, it should be recognizable that therefore, inside and outside quotes, three double-quotes act as a plain-text unescaped double-quote:
will print
Tim said to him, "What's been happening lately?"
as expected. Therefore, three quotes can always be reliably used as an escape.However, in understanding it, you may note that the four quotes at the end can be reduced to a mere two since it technically is adding another unnecessary empty double-quoted group.
Here are a few examples to close it off:
Final note: I did not read any of this from any tutorial - I came up with all of it by experimenting. Therefore, my explanation may not be true internally. Nonetheless all the examples above evaluate as given, thus validating (but not proving) my theory.
I tested this on Windows 7, 64bit using only *.exe calls with parameter passing (not *.bat, but I would suppose it works the same).
我无法快速重现症状:如果我尝试使用仅包含
@echo.%1
的批处理文件myscript.bat
来执行myscript '"test"'
> 甚至@echo.%~1
,我得到所有引号:'"test"'
也许你可以尝试转义字符
^
像这个:myscript '^“测试^”'
?I cannot quickly reproduce the symptoms: if I try
myscript '"test"'
with a batch filemyscript.bat
containing just@echo.%1
or even@echo.%~1
, I get all quotes:'"test"'
Perhaps you can try the escape character
^
like this:myscript '^"test^"'
?试试这个:
“”转义到参数中的单个“。
Try this:
"" escape to a single " in the parameter.
Peter Mortensen 在对 Codesmith 的答案的评论中引用的第二份文件让我的情况变得更加清晰。该文档由 windowsinspired.com 编写。链接重复: 理解 Windows 命令行参数的引用和转义的更好方法。
一些进一步的试验和错误导致以下准则:
使用脱字符号
^
转义每个双引号"
。如果您想要其他对 Windows 命令具有特殊含义的字符shell(例如,<
、>
、|
、&
)被解释为常规字符,然后也用插入符号转义它们。如果你愿意您的程序 foo 接收命令行文本
"a\"b c" > d
并将其输出重定向到文件 out.txt,然后从 Windows 命令 shell 启动程序,如下所示:如果 foo 解释
\"< /code> 作为文字双引号,并期望非转义双引号来分隔包含空格的参数,然后 foo 将命令解释为指定一个参数
和一个参数a"b c
,一个参数 < code>>d
。相反,如果 foo 将双双引号
""
解释为文字双引号,则将程序启动为引用文档的关键见解是,对于 Windows 命令 shell ,未转义的双引号会触发两种可能状态之间的切换。
一些进一步的试验和错误意味着在初始状态下,重定向(到文件或管道)被识别,插入符号
^
转义双引号,并且插入符号从输入中删除。在另一种状态下,无法识别重定向,并且插入符号不会转义双引号并且不会被删除。我们将这些状态分别称为“外部”和“内部”。如果要重定向命令的输出,则命令 shell 在到达重定向时必须处于外部状态,因此重定向之前必须有偶数个未转义(通过插入符号)的双引号。
foo "a\"b " > out.txt
不起作用——命令 shell 传递整个"a\"b " > out.txt
到 foo 作为其组合命令行参数,而不是仅传递"a\"b "
并将输出重定向到 out。 txt.foo "a\^"b " >. out.txt
也不起作用,因为插入符号^
是在内部状态中遇到的,它是普通字符而不是转义字符,因此"a\ ^"b " > out.txt
被传递给 foo。(希望)始终有效的唯一方法是使命令 shell 始终处于外部状态,因为这样重定向就可以工作。如果
不需要重定向(或其他具有特殊含义的字符)如果 foo 将
\"
解释为文字双引号,那么您可以将其称为“Then foo” 。 接收
"a\"b c"
作为其组合参数文本,并可以将其解释为等于a"b c
的单个参数。现在——最后——回到最初的问题。从 Windows 命令 shell 调用的
myscript '"test"'
将'"test"'
传递给 myscript。显然 myscript 将单引号和双引号解释为参数分隔符并将其删除。您需要弄清楚 myscript 接受什么作为文字双引号,然后在命令中指定它,使用^
转义对 Windows 命令 shell 有特殊含义的任何字符。鉴于myscript
在 Unix 上也可用,也许\"
可以解决问题。尝试或者,如果您不需要重定向,
The 2nd document quoted by Peter Mortensen in his comment on the answer of Codesmith made things much clearer for me. That document was written by windowsinspired.com. The link repeated: A Better Way To Understand Quoting and Escaping of Windows Command Line Arguments.
Some further trial and error leads to the following guideline:
Escape every double quote
"
with a caret^
. If you want other characters with special meaning to the Windows command shell (e.g.,<
,>
,|
,&
) to be interpreted as regular characters instead, then escape them with a caret, too.If you want your program foo to receive the command line text
"a\"b c" > d
and redirect its output to file out.txt, then start your program as follows from the Windows command shell:If foo interprets
\"
as a literal double quote and expects unescaped double quotes to delimit arguments that include whitespace, then foo interprets the command as specifying one argumenta"b c
, one argument>
, and one argumentd
.If instead foo interprets a doubled double quote
""
as a literal double quote, then start your program asThe key insight from the quoted document is that, to the Windows command shell, an unescaped double quote triggers switching between two possible states.
Some further trial and error implies that in the initial state, redirection (to a file or pipe) is recognized and a caret
^
escapes a double quote and the caret is removed from the input. In the other state, redirection is not recognized and a caret does not escape a double quote and isn't removed. Let's refer to these states as 'outside' and 'inside', respectively.If you want to redirect the output of your command, then the command shell must be in the outside state when it reaches the redirection, so there must be an even number of unescaped (by caret) double quotes preceding the redirection.
foo "a\"b " > out.txt
won't work -- the command shell passes the entire"a\"b " > out.txt
to foo as its combined command line arguments, instead of passing only"a\"b "
and redirecting the output to out.txt.foo "a\^"b " > out.txt
won't work, either, because the caret^
is encountered in the inside state where it is an ordinary character and not an escape character, so"a\^"b " > out.txt
gets passed to foo.The only way that (hopefully) always works is to keep the command shell always in the outside state, because then redirection works.
If you don't need redirection (or other characters with special meaning to the command shell), then you can do without the carets. If foo interprets
\"
as a literal double quote, then you can call it asThen foo receives
"a\"b c"
as its combined arguments text and can interpret it as a single argument equal toa"b c
.Now -- finally -- to the original question.
myscript '"test"'
called from the Windows command shell passes'"test"'
to myscript. Apparently myscript interprets the single and double quotes as argument delimiters and removes them. You need to figure out what myscript accepts as a literal double quote and then specify that in your command, using^
to escape any characters that have special meaning to the Windows command shell. Given thatmyscript
is also available on Unix, perhaps\"
does the trick. Tryor, if you don't need redirection,
我从 cmd 调用 powershell,并传递引号,但这里的转义都不起作用。在这个 Win 10 Surface Pro 上,重音可以用来转义双引号。
以下是我得到的其他字符转义双引号的输出:
使用另一个引号转义引号导致没有引号。
正如您所看到的,字符本身已被键入,但没有转义双引号。
I'm calling powershell from cmd, and passing quotes and neither escapes here worked. The grave accent worked to escape double quotes on this Win 10 surface pro.
Below are outputs I got for other characters to escape a double quote:
Using another quote to escape a quote resulted in no quotes.
As you can see, the characters themselves got typed, but didn't escape the double quotes.
也许您来到这里,是因为您想知道如何转义在
cmd.exe
上传递给/c
的命令中所需的引号?好吧,你不:将执行,
这确实是我乍一看没想到的行为。
Maybe you came here, because you wonder how to escape quotes that you need in the command that you pass to
/c
oncmd.exe
? Well you don't:will execute
which is really a behavior that I did not expect in the first glance.