Как мне работать с символами кавычек при использовании cmd.exe - PullRequest
55 голосов
/ 10 декабря 2008

Я пытаюсь сделать это:

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 ]

71 голосов
/ 10 декабря 2008

Ах. DOH. Думаю, я ответил на свой вопрос.

Если вы используете / S и заключаете все в кавычки, это просто удаляет эти внешние кавычки.

cmd.exe /S /C " do what you like here, quotes within the outermost quotes will be preserved "
9 голосов
/ 18 декабря 2012

Я думаю, вы обнаружите, что ваш пример работает абсолютно нормально.

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"

и то, как / почему он работает так, как работает, потому что> хост интерпретируется как> специальный. Так что эта часть cmd.exe /C "C:\Program Files\Somewhere\SomeProgram.exe" - я думаю - оценивается первой. т.е. cmd / c не видит> и после.

смд /? показывает 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 передается> узлом cmd.exe, и поэтому вызываемый cmd.exe выполняет перенаправление. Также, конечно, ваш пример - это случай 1, а ваше решение - это поправка, которую вы внесли (очень хорошо), чтобы она работала в случае 2.

Надеюсь, я здесь не ошибся, возможно. Но ваш вопрос и ответ помогли мне понять, как работает cmd и, в частности, cmd / c!

Возможно, ваш пример был упрощением вашего фактического, а ваш действительный потерпел неудачу и нуждался в вашей поправке. Если ваш пример был немного более сложным, например, с параметром для программы, которая принимает кавычки, то он бы потерпел неудачу в случае 1, и вам действительно потребуются внешние кавычки (/ S не изменит результат , поэтому нет необходимости в / S, так как это уже будет случай 2, когда вы добавите необходимые внешние кавычки). Но пример, который вы привели в своем вопросе, на самом деле мне кажется, работает нормально.

Добавлено - связанные вопросы и ответы Для чего используется cmd / s?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...