转义参数中的双引号

时间:2011-10-13 21:17:22

标签: windows cmd

在Unix中,我可以运行myscript '"test"',我会得到"test"

在Windows cmd中,我得到'test'

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

5 个答案:

答案 0 :(得分:172)

另一种逃避引用的方法(虽然可能不太可取),我发现在某些地方使用的是使用多个双引号。为了使其他人的代码清晰可见,我将解释。

这是一套基本规则:

  1. 如果未包含在双引号组中,则空格分隔参数:
    program param1 param2 param 3会将四个参数传递给program.exe
    param1,{{1} },param2param
  2. 双引号组在将参数传递给程序时忽略空格作为值分隔符:
    3会将三个参数传递给program one two "three and more"
    program.exe,{ {1}}和one
  3. 现在解释一些困惑:
  4. 与未使用双引号括起的文字直接相邻的双引号组合并为一个参数:
    two充当一个参数:three and more
  5. 注意:之前的规则并不意味着两个双引号组可以直接相邻显示。
  6. 直接在结束引用之后的任何双引号被视为与双引号组相邻的普通未包装文本(或作为其一部分),但只有一个双引号:
    hello"to the entire"world将作为一个参数:helloto the entireworld
  7. 因此,有三种不同类型的双引号:打开的引号,关闭的引号和作为纯文本的引号。
    这是最后一个混乱线的细分:

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

    因此,文本有效地连接了四组角色(一组没有,但是): "Tim says, ""Hi!"""是第一个被包裹以逃避空间的 Tim says, "Hi!"是第二个,没有包裹(没有空格)
    Tim says, 是第三个,双引号组不包括任何内容 "Hi!是第四个,未打开的近距离报价。

    正如你所看到的,双引号组不包含任何内容仍然是必要的,因为如果没有它,下面的双引号会打开一个双引号组,而不是作为纯文本。

    由此可见,因此,在内部和外部引号中,三个双引号充当纯文本未转义的双引号:

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

    将按预期打印。因此,三个引号总是可以被可靠地用作逃避。
    但是,在理解它时,您可能会注意到最后的四个引号可以减少到仅仅两个,因为它在技术上增加了另一个不必要的空双 - 引用组。

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

    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,64bit上测试了这个,只使用* .exe调用参数传递(不是* .bat,但我认为它的工作原理相同)。

答案 1 :(得分:21)

试试这个:

myscript """test"""
在参数中

“”转义为单个“。

答案 2 :(得分:16)

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

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

答案 3 :(得分:0)

彼得·莫滕森(Peter Mortensen)在他对Codesmith的回答的评论中引用的第二份文件对我来说更清楚了。该文档由windowsinspired.com编写。链接重复: A Better Way To Understand Quoting and Escaping of Windows Command Line Arguments

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

使用尖号"来删除每个双引号^。如果要将Windows命令行解释程序中具有特殊含义的其他字符(例如<>|&)解释为常规字符,请转义他们也有尖号。

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

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

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

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

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

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

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

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

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

(希望)始终有效的唯一方法是将命令外壳始终保持在外部状态,因为这样重定向才能起作用。

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

foo "a\"b c"

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

现在-终于-原来的问题了。从Windows命令外壳调用的myscript '"test"''"test"'传递给 myscript 。显然, myscript 将单引号和双引号解释为参数定界符,并将其删除。您需要弄清楚 myscript 接受为文字双引号,然后在命令中使用^进行指定,以转义Windows命令外壳中所有具有特殊含义的字符。鉴于myscript在Unix上也可用,也许\"可以解决问题。试试

myscript \^"test\^"

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

myscript \"test\"

答案 4 :(得分:0)

我正在从cmd调用powershell,并传递引号,但此处的转义符均无效。重音使这个Win 10 Surface Pro避免了双引号。

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

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

la\
la^
la
la~

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