windows 在参数中转义双引号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7760545/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 08:48:54  来源:igfitidea点击:

Escape double quotes in parameter

windowscmd

提问by Bryan Field

In Unix I could run myscript '"test"'and I would get "test".

在 Unix 中我可以运行myscript '"test"'并且我会得到"test".

In Windows cmdI get 'test'.

在 Windows 中,cmd我得到'test'.

How can I pass double-quotes as a parameter? I would like to know how to do this manually from a cmdwindow so I don't have to write a program to test my program.

如何将双引号作为参数传递?我想知道如何从cmd窗口手动执行此操作,这样我就不必编写程序来测试我的程序。

采纳答案by mousio

I cannot quickly reproduce the symptoms: if I try myscript '"test"'with a batch file myscript.batcontaining just @echo.%1or even @echo.%~1, I get all quotes: '"test"'

我无法快速重现症状:如果我尝试myscript '"test"'使用myscript.bat仅包含@echo.%1或 even的批处理文件@echo.%~1,我会得到所有引号:'"test"'

Perhaps you can try the escape character ^like this: myscript '^"test^"'?

也许您可以尝试这样的转义字符^myscript '^"test^"'?

回答by Codesmith

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:

这是一组基本规则:

  1. When not wrapped in double-quoted groups, spaces separate parameters:
    program param1 param2 param 3will pass four parameters to program.exe:
         param1, param2, param, and 3.
  2. A double-quoted group ignores spaces as value separators when passing parameters to programs:
    program one two "three and more"will pass three parameters to program.exe:
         one, two, and three and more.
  3. Now to explain some of the confusion:
  4. Double-quoted groups that appear directly adjacent to text not wrapped with double-quotes join into one parameter:
    hello"to the entire"worldacts as one parameter: helloto the entireworld.
  5. Note: The previous rule does NOT imply that two double-quoted groups can appear directly adjacent to one another.
  6. Any double-quote directly following a closing quoteis treated as (or as part of) plain unwrapped text that is adjacent to the double-quoted group, but only one double-quote:
    "Tim says, ""Hi!"""will act as one parameter: Tim says, "Hi!"
  1. 如果不是用双引号组,空格分隔参数:
    program param1 param2 param 3将通过四个参数program.exe
         param1param2param,和3
  2. 双引号组忽略空格作为参数传递给程序时价值分离:
    program one two "three and more"将通过三个参数program.exe
         onetwothree and more
  3. 现在解释一些混淆:
  4. 直接出现在未用双引号包裹的文本旁边的双引号组加入一个参数:
    hello"to the entire"world作为一个参数:helloto the entireworld
  5. 注意:上一条规则并不意味着两个双引号组可以直接相邻出现。
  6. 紧跟在结束引号之后的任何双引号都被视为(或作为)与双引号组相邻的普通展开文本的一部分,但只有一个双引号:
    "Tim says, ""Hi!"""将作为一个参数: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:

因此,存在三种不同类型的双引号:打开的引号、关闭的引号和充当纯文本的引号。
这是最后一个令人困惑的行的细分:

"   open double-quote group
T   inside ""s
i   inside ""s
m   inside ""s
    inside ""s - space doesn't separate
s   inside ""s
a   inside ""s
y   inside ""s
s   inside ""s
,   inside ""s
    inside ""s - space doesn't separate
"   close double-quoted group
"   quote directly follows closer - acts as plain unwrapped text: "
H   outside ""s - gets joined to previous adjacent group
i   outside ""s - ...
!   outside ""s - ...
"   open double-quote group
"   close double-quote group
"   quote directly follows closer - acts as plain unwrapped text: "

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.

因此,文本有效地连接了四组字符(但是,一个没有任何字符):
Tim says,  是第一个,包裹以转义空格
"Hi!第二个,未包裹(没有空格)
 第三个,双引号组,不包裹任何内容
"是第四个,展开的关闭引号。

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:

由此,应该可以看出,因此,内外引号,三个双引号充当纯文本未转义双引号:

"Tim said to him, """What's been happening lately?""""

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.

将按Tim said to him, "What's been happening lately?"预期打印。因此,始终可以可靠地将三个引号用作转义符。
但是,在理解它时,您可能会注意到末尾的四个引号可以减少到仅仅两个,因为它在技术上添加了另一个不必要的空双引号组。

Here are a few examples to close it off:

以下是一些关闭它的示例:

program a b                       REM sends (a) and (b)
program """a"""                   REM sends ("a")
program """a b"""                 REM sends ("a) and (b")
program """"Hello,""" Mike said." REM sends ("Hello," Mike said.)
program ""a""b""c""d""            REM sends (abcd) since the "" groups wrap nothing
program "hello to """quotes""     REM sends (hello to "quotes")
program """"hello world""         REM sends ("hello world")
program """hello" world""         REM sends ("hello world")
program """hello "world""         REM sends ("hello) and (world")
program "hello ""world"""         REM sends (hello "world")
program "hello """world""         REM sends (hello "world")

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).

我仅使用带有参数传递的 *.exe 调用(不是 *.bat,但我认为它的工作原理相同)在 64 位 Windows 7 上对此进行了测试。

回答by smwikipedia

Try this:

尝试这个:

myscript """test"""

"" escape to a single " in the parameter.

"" 转义到参数中的单个 "。

回答by Louis Strous

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.

Peter Mortensen 在他对 Codesmith 回答的评论中引用的第二份文件让我更清楚地了解情况。该文档由 windowsinspired.com 编写。链接重复:一个更好的方法来理解 Windows 命令行参数的引用和转义

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.

"用插入符号转义每个双引号^。如果您希望其他对 Windows 命令外壳具有特殊含义的字符(例如,<, >, |, &)被解释为常规字符,那么也可以使用插入符号将它们转义。

If you want your program footo receive the command line text "a\"b c" > dand redirect its output to file out.txt, then start your program as follows from the Windows command shell:

如果您希望程序foo接收命令行文本"a\"b c" > d并将其输出重定向到文件out.txt,则从 Windows 命令外壳启动您的程序,如下所示:

foo ^"a\^"b c^" ^> d > out.txt

If foointerprets \"as a literal double quote and expects unescaped double quotes to delimit arguments that include whitespace, then foointerprets the command as specifying one argument a"b c, one argument >, and one argument d.

如果foo解释\"为文字双引号并期望未转义的双引号分隔包含空格的参数,则foo将命令解释为指定一个参数a"b c、一个参数>和一个参数d

If instead foointerprets a doubled double quote ""as a literal double quote, then start your program as

相反,如果foo将双双引号解释""为文字双引号,则将程序启动为

foo ^"a^"^"b c^" ^> d > out.txt

The key insight from the quoted document is that, to the Windows command shell, an unescaped double quote triggers switching between two possible states.

引用文档的关键见解是,对于 Windows 命令外壳,未转义的双引号会触发两种可能状态之间的切换。

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.txtwon't work -- the command shell passes the entire "a\"b " > out.txtto fooas its combined command line arguments, instead of passing only "a\"b "and redirecting the output to out.txt.

如果要重定向命令的输出,那么命令外壳程序在到达重定向时必须处于外部状态,因此在重定向之前必须有偶数个未转义(插入符号)的双引号。 foo "a\"b " > out.txt不起作用——命令外壳将整个传递"a\"b " > out.txtfoo作为其组合命令行参数,而不是仅传递"a\"b "并将输出重定向到out.txt

foo "a\^"b " > out.txtwon'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.txtgets passed to foo.

foo "a\^"b " > out.txt也不会工作,因为插入符号^是在内部状态中遇到的,它是一个普通字符而不是转义字符,所以"a\^"b " > out.txt被传递给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 foointerprets \"as a literal double quote, then you can call it as

如果您不需要重定向(或其他对命令 shell 具有特殊含义的字符),那么您可以不用插入符号。如果foo解释\"为文字双引号,那么您可以将其称为

foo "a\"b c"

Then fooreceives "a\"b c"as its combined arguments text and can interpret it as a single argument equal to a"b c.

然后foo接收"a\"b c"作为它的组合参数 text 并且可以将其解释为等于 的单个参数a"b c

Now -- finally -- to the original question. myscript '"test"'called from the Windows command shell passes '"test"'to myscript. Apparently myscriptinterprets the single and double quotes as argument delimiters and removes them. You need to figure out what myscriptaccepts 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 that myscriptis also available on Unix, perhaps \"does the trick. Try

现在 - 最后 - 到最初的问题。 myscript '"test"'从 Windows 命令外壳调用传递'"test"'myscript。显然myscript将单引号和双引号解释为参数分隔符并删除它们。您需要弄清楚myscript接受什么作为文字双引号,然后在您的命令中指定它,^用于转义对 Windows 命令外壳具有特殊含义的任何字符。鉴于这myscript在 Unix 上也可用,也许\"可以解决问题。尝试

myscript \^"test\^"

or, if you don't need redirection,

或者,如果您不需要重定向,

myscript \"test\"

回答by Zimba

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.

我正在从 cmd 调用 powershell,并传递引号,这里没有任何转义。在这个 Win 10 Surface Pro 上,重音可以避免双引号。

>powershell.exe "echo la`"" >> test
>type test
la"

Below are outputs I got for other characters to escape a double quote:

以下是我为其他字符转义双引号得到的输出:

la\
la^
la
la~

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.

使用另一个引号来转义引号导致没有引号。如您所见,字符本身被输入,但没有转义双引号。