在参数中转义双引号

发布于 2024-12-09 11:52:32 字数 214 浏览 1 评论 0原文

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

星星的轨迹 2024-12-16 11:52:32

我发现在某些地方使用的另一种转义引号的方法(尽管可能不是首选)是使用多个双引号。为了使其他人的代码清晰易读,我将进行解释。

以下是一组基本规则:

  1. 当未用双引号组括起来时,请用空格分隔参数:
    program param1 param2 param 3 会将四个参数传递给 program.exe< /code>:
         param1param2param 和<代码>3。
  2. 在向程序传递参数时,双引号组会忽略空格作为值分隔符:
    程序一二“三及更多” 将向 program.exe 传递三个参数:
       一个两个三个及更多
  3. Now to explain some of the confusion:

  4. 与未用双引号括起来的文本直接相邻的双引号组连接到一个参数中:
    hello"to the another"world 充当一个参数:helloto the anotherworld< /代码>。
  5. Note: The previous rule does NOT imply that two double-quoted groups can appear directly adjacent to one another.

  6. 任何直接跟在结束引号后面的双引号都被视为(或作为一部分)与双引号组相邻的纯展开文本,但只有一个双引号:
    "Tim said, ""Hi!""" 将充当一个参数: Tim said, "Hi!"

因此,存在三种不同类型的双引号: 、结束引号以及充当纯文本。
这是最后令人困惑的一行的细分:

"   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: "

因此,文本有效地连接了四组字符(但是其中一组没有任何字符):
蒂姆说, 是第一个,包裹起来以逃避空格
“Hi!是第二个,未换行(没有空格)
 是第三个,双引号组不包含任何内容
" 是第四个,展开的闭引号。

如您所见,不包含任何内容的双引号组仍然是必要的,因为如果没有它,下面的双引号将打开一个双引号组 将打印 Tim said to his

从这里,应该可以看出,因此,在引号内部和外部,三个双引号充当纯文本未转义双引号:

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

, "What's到过最近发生了什么?” 正如预期的那样。因此,三个引号始终可以可靠地用作转义。
但是,在理解它时,您可能会注意到末尾的四个引号可以减少到仅仅两个因为从技术上讲,它添加了另一个不必要的空双引号组,

以下是一些将其关闭的示例:

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

最后一点:我没有从任何教程中阅读任何内容 - 我通过实验想出了所有这些内容。尽管如此,上述所有示例的内部解释可能并不正确。正如给定的,从而验证(但不是证明)我的理论。

我在 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:

  1. When not wrapped in double-quoted groups, spaces separate parameters:
    program param1 param2 param 3 will 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"world acts 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 quote is 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!"

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.

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.

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

不一样的天空 2024-12-16 11:52:32

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

也许你可以尝试转义字符 ^ 像这个:myscript '^“测试^”'

I cannot quickly reproduce the symptoms: if I try myscript '"test"' with a batch file myscript.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^"'?

み格子的夏天 2024-12-16 11:52:32

试试这个:

myscript """test"""

“”转义到参数中的单个“。

Try this:

myscript """test"""

"" escape to a single " in the parameter.

香草可樂 2024-12-16 11:52:32

Peter Mortensen 在对 Codesmith 的答案的评论中引用的第二份文件让我的情况变得更加清晰。该文档由 windowsinspired.com 编写。链接重复: 理解 Windows 命令行参数的引用和转义的更好方法

一些进一步的试验和错误导致以下准则:

使用脱字符号 ^ 转义每个双引号 "。如果您想要其他对 Windows 命令具有特殊含义的字符shell(例如,<>|&)被解释为常规字符,然后也用插入符号转义它们。

如果你愿意您的程序 foo 接收命令行文本 "a\"b c" > d 并将其输出重定向到文件 out.txt,然后从 Windows 命令 shell 启动程序,如下所示:

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

如果 foo 解释 \"< /code> 作为文字双引号,并期望非转义双引号来分隔包含空格的参数,然后 foo 将命令解释为指定一个参数 a"b c,一个参数 < code>> 和一个参数d

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

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

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

一些进一步的试验和错误意味着在初始状态下,重定向(到文件或管道)被识别,插入符号 ^ 转义双引号,并且插入符号从输入中删除。在另一种状态下,无法识别重定向,并且插入符号不会转义双引号并且不会被删除。我们将这些状态分别称为“外部”和“内部”。

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

foo "a\^"b " >. out.txt 也不起作用,因为插入符号 ^ 是在内部状态中遇到的,它是普通字符而不是转义字符,因此 "a\ ^"b " > out.txt 被传递给 foo

(希望)始终有效的唯一方法是使命令 shell 始终处于外部状态,因为这样重定向就可以工作。如果

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

foo "a\"b c"

Then foo” 。 接收 "a\"b c" 作为其组合参数文本,并可以将其解释为等于 a"b c 的单个参数。

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

myscript \^"test\^"

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

myscript \"test\"

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:

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

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 argument a"b c, one argument >, and one argument d.

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

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.

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 as

foo "a\"b c"

Then foo receives "a\"b c" as its combined arguments text and can interpret it as a single argument equal to a"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 that myscript is also available on Unix, perhaps \" does the trick. Try

myscript \^"test\^"

or, if you don't need redirection,

myscript \"test\"
鸢与 2024-12-16 11:52:32

我从 cmd 调用 powershell,并传递引号,但这里的转义都不起作用。在这个 Win 10 Surface Pro 上,重音可以用来转义双引号。

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

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

la\
la^
la
la~

使用另一个引号转义引号导致没有引号。
正如您所看到的,字符本身已被键入,但没有转义双引号。

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.

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

随梦而飞# 2024-12-16 11:52:32

也许您来到这里,是因为您想知道如何转义在 cmd.exe 上传递给 /c 的命令中所需的引号?好吧,你不:

CMD /c "MKDIR "foo bar""

将执行,

MKDIR "foo bar"

这确实是我乍一看没想到的行为。

Maybe you came here, because you wonder how to escape quotes that you need in the command that you pass to /c on cmd.exe? Well you don't:

CMD /c "MKDIR "foo bar""

will execute

MKDIR "foo bar"

which is really a behavior that I did not expect in the first glance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文