使用cmd.exe时如何处理引号字符

时间:2008-12-10 13:10:24

标签: windows command-line

我正在尝试这样做:

cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out"

但是,我遇到的问题与cmd.exe的工作方式有关。如果您阅读了它的帮助,它会以一种特殊的方式处理“字符。请查看问题末尾的帮助。所以,这不能正确执行...我猜测cmd.exe剥离了一些引号,这使得陈述不正确。

我可以成功地做到这一点:

// quotes not required around folder with no spaces
cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > C:\temp\FolderWithNoSpaces\SomeProgram.out

但是,我真的需要第一个工作。是否存在cmd.exe使用的奇怪报价处理?我希望它能保留所有引号,但似乎没有选择让它做到这一点。


从输出中获取帮助:cmd /?

如果指定了/ C或/ K,那么后面的命令行的其余部分 交换机作为命令行处理,其中包含以下逻辑 用于处理引号(“)字符:

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

2 个答案:

答案 0 :(得分:71)

阿。卫生署。我想我已回答了自己的问题。

如果你使用/ S,并用引号包装整个东西,它只是删除那些外引号。

cmd.exe /S /C " do what you like here, quotes within the outermost quotes will be preserved "

答案 1 :(得分:9)

我想你会发现你的例子工作得非常好。

cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out"

我在这里复制了你的例子 http://pastebin.com/raw.php?i=YtwQXTGN

C:\>cmd /c "c:\Program Files\my folder\my long program.exe" > "c:\temp\spaces are here\a.a"

C:\>type "c:\temp\spaces are here\a.a"
my long program.exe has run

C:\>

further example demonstrating it works with "my long program.exe", removing cmd /c, it operates fine too.

C:\>"c:\Program Files\my folder\my long program.exe" > "c:\temp\spaces are here\
a.a"

C:\>type "c:\temp\spaces are here\a.a"
my long program.exe has run

C:\>



Another example, but with replace.  replace with no parameters says "source path required"  "no files replaced"

C:\>replace > a.a
Source path required

C:\>type a.a
No files replaced

Exactly the same effect when they're in folders with spaces.

C:\>cmd /c "c:\Program Files\my folder\replace.exe" > "c:\temp\spaces are here\r.r"
Source path required

C:\>type "c:\temp\spaces are here\r.r"
No files replaced

C:\>

further demonstration with replace
without cmd /c works fine too.

C:\>"c:\Program Files\my folder\replace.exe" > "c:\temp\spaces are here\r.r"
Source path required

C:\>type "c:\temp\spaces are here\r.r"
No files replaced

C:\>

您的示例正常工作的原因

cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out"

以及它如何/为什么以它的方式工作,是因为&gt;由host.exe解释为特殊所以这部分cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" - 我认为 - 首先进行评估。即cmd / c没有看到&gt;之后。

cmd /?显示2例

案例1和案例2.您的示例适合案例1

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.

您可以测试您的示例是否适合案例1,因为如果您添加/ s(不添加任何引号或对您的示例进行任何更改除了添加/ s),那么您会得到不同的结果,因为它使你的例子命中案例2.所以证明你的例子肯定是一个案例1.它明显符合案例1的所有标准。 如果您的示例是案例2,并且您添加了/ s,则它没有任何区别。

您的回答很有趣,因为它显示了另一种获取结果的方法,但是在案例2中。通过添加额外的引号并添加/ s。

但实际上,当你添加那些额外的引号时,你刚刚把它作为案例2,并且在它之上添加一个/ s将没有什么区别。

C:\>cmd /c "c:\Program Files\my folder\replace.exe"
Source path required
No files replaced

C:\>cmd /s /c "c:\Program Files\my folder\replace.exe"
'c:\Program' is not recognized as an internal or external command,
operable program or batch file.

C:\>cmd /c ""c:\Program Files\my folder\replace.exe""
Source path required
No files replaced

C:\>cmd /s /c ""c:\Program Files\my folder\replace.exe""
Source path required
No files replaced

C:\>

您问题中的示例工作正常

cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out"

您提供的替代方案(使用/ S和外部引号)作为示例工作的答案,也可以正常工作

cmd.exe /S /C ""C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out""

虽然您的答案可以替代,但实际上可以通过删除/ S来简化,因为它已经是案例2,所以添加/ s不会有任何区别。因此,这将改进您的答案中给出的解决方案

cmd.exe /C ""C:\Program Files\Somewhere\SomeProgram.exe" > "C:\temp\Folder Containing Spaces\SomeProgram.out""

您在问题中描述为问题的示例以及您的解决方案会产生相同的效果。但是我认为有一个很大的区别,(我不确定如何测试它),但是你的例子的工作方式和你的答案中解决方案的工作方式有所不同,我认为就你的例子来说,托管/调用cmd.exe会重定向到该文件。而在您的解决方案示例中,调用的cmd.exe传递了&gt;由主机cmd.exe,因此调用的cmd.exe执行重定向。当然,你的例子也是一个案例1,而你的解决方案是你做的一个修正案(很好),使其在案例2中有效。

我希望我在这里没有错,我可能有。但是你的问题和答案确实帮助我了解cmd,特别是cmd / c是如何工作的!

也许你的例子过于简单化了你的实例,而你的实际确实失败并需要你的修正。如果您的示例案例稍微复杂一点,例如,为程序的参数设置参数,那么它就会失败案例1,你确实需要更多的引号(/ S不会改变结果) ,所以没有/ S是必要的,因为一旦你添加了那些需要的外部引号,它已经是一个案例2)。但是你在问题中给出的例子在我看来实际上可以正常工作。

已添加 - 相关的Q和A What is `cmd /s` for?