Двойные кавычки в командной строке windows

I'm trying to do this: cmd.exe /C "C:Program FilesSomewhereSomeProgram.exe" > "C:tempFolder Containing SpacesSomeProgram.out" However, I have problems which are down to the way cmd.exe w...

I think you’ll find that your example works absolutely fine as it is.

cmd.exe /C "C:Program FilesSomewhereSomeProgram.exe" > "C:tempFolder Containing SpacesSomeProgram.out"

I have reproduced your example here
http://pastebin.com/raw.php?i=YtwQXTGN

C:>cmd /c "c:Program Filesmy foldermy long program.exe" > "c:tempspaces are herea.a"

C:>type "c:tempspaces are herea.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 Filesmy foldermy long program.exe" > "c:tempspaces are here
a.a"

C:>type "c:tempspaces are herea.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 Filesmy folderreplace.exe" > "c:tempspaces are herer.r"
Source path required

C:>type "c:tempspaces are herer.r"
No files replaced

C:>

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

C:>"c:Program Filesmy folderreplace.exe" > "c:tempspaces are herer.r"
Source path required

C:>type "c:tempspaces are herer.r"
No files replaced

C:>

The reason why your example works fine

cmd.exe /C "C:Program FilesSomewhereSomeProgram.exe" > "C:tempFolder Containing SpacesSomeProgram.out"

and how/why it works the way it does, is because the > is interpreted as special by the host.exe So this part cmd.exe /C "C:Program FilesSomewhereSomeProgram.exe" — I think — is evaluated first. i.e. cmd /c does not see the > and after.

cmd /? shows 2 cases

Case 1 and Case 2. Your example fits Case 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.

You can test for sure that your example fits case 1, because if you add /s (without adding any more quotes or making any change at all to your example other than adding /s), then you get a different result, because it makes your example hit case 2. So that proves that your example is definitely a case 1. And it clearly meets all the criteria of case 1.
If your example were a case 2, and you added /s, then it’d make no difference.

Your answer is interesting because it shows an alternative way of getting your result, but in case 2. By adding additional outter quotes and adding /s.

But actually, when you add those additional outter quotes, then you’ve just made it a case 2, and adding a /s on top of that won’t make a difference.

C:>cmd /c "c:Program Filesmy folderreplace.exe"
Source path required
No files replaced

C:>cmd /s /c "c:Program Filesmy folderreplace.exe"
'c:Program' is not recognized as an internal or external command,
operable program or batch file.

C:>cmd /c ""c:Program Filesmy folderreplace.exe""
Source path required
No files replaced

C:>cmd /s /c ""c:Program Filesmy folderreplace.exe""
Source path required
No files replaced

C:>

The example in your question worked fine

cmd.exe /C "C:Program FilesSomewhereSomeProgram.exe" > "C:tempFolder Containing SpacesSomeProgram.out"

Your alternative (with the /S and outer quotes) you give as an answer to make the example work, works fine too

cmd.exe /S /C ""C:Program FilesSomewhereSomeProgram.exe" > "C:tempFolder Containing SpacesSomeProgram.out""

Though your answer which is an alternative, can actually be simplified by removing the /S because it’s already a case 2, so adding /s won’t make any difference. So this would improve the solution given in your answer

cmd.exe /C ""C:Program FilesSomewhereSomeProgram.exe" > "C:tempFolder Containing SpacesSomeProgram.out""

Your example which you described as a problem in your question, and your solution, produce the same good result. But one big difference I suppose, (and I am not sure how to test for it), but one difference in the way your example works, and the way the solution in your answer works, is I think in the case of your example, the hosting/invoking cmd.exe does the redirect to the file. Whereas in your solution’s example, the invoked cmd.exe is passed the > by the host cmd.exe, and so the invoked cmd.exe does the redirect. Also of course, your example is a case 1, while your solution is an amendment you made (very well) to make it work in case 2.

I hope I haven’t erred here, I may have. But your question and answer did help me wrap my head around how cmd and in particular cmd /c is working!

Perhaps your example was an oversimplification of your actual one, and your actual one did fail and needed your amendment. If your example case, had been a tiny bit more complex, by for example, having a parameter to the program that took quotes, then it’d fail Case 1, and you would indeed need outter quotes (/S would not change the result, so no /S would be necessary, as it’d already be a case 2 once you add those needed outer quotes). But the example you gave in your question actually seems to me to work fine.

Added — A related Q and A What is `cmd /s` for?

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"

собственный ответ eplawless просто и эффективно решает его конкретную проблему: заменяет все " экземпляры во всем списке аргументов с ", поэтому Bash требует, чтобы в строке с двойными кавычками были представлены двойные кавычки.

Чтобы в целом ответить на вопрос о как избежать двойных кавычек внутри строки с двойными кавычками, используя cmd.exe, интерпретатор командной строки Windows (будь то в командной строке — часто ошибочно называемой «подсказкой DOS» — или в пакетном файле):См. Внизу, чтобы посмотреть на PowerShell.

ТЛ; др:

  • Ты должен использование "" при передаче строки к другому) командный файл и ты май использование "" с приложениями, созданными с Microsoftкомпиляторы C / C ++ /. NET (который Также принимать "), который в Windows включает Python и Node.js:

    • Пример: foo.bat "We had 3"" of rain."

    • Следующее относится только к пакетным файлам:

      • "" — единственный способ получить командный интерпретатор (cmd.exe) для обработки всей строки в двойных кавычках как одинарной аргумент.

      • К сожалению, однако, сохраняются не только закрывающие двойные кавычки (как обычно), но и двойные экранированные кавычки, поэтому получение предполагаемой строки представляет собой двухэтапный процесс; например, предполагая, что строка в двойных кавычках передается как 1-й аргумент, %1:

      • set "str=%~1" удаляет заключительные двойные кавычки; set "str=%str:""="%" затем преобразует двойные двойные кавычки в одинарные.
        Обязательно заключите части присваивания в двойные кавычки, чтобы предотвратить нежелательную интерпретацию значений.

  • " is обязательный — как единственный вариант — многими другими программами, (например, Ruby, Perl и даже собственная оболочка Microsoft Windows PowerShell (!)), но ЕГО ИСПОЛЬЗОВАНИЕ НЕ БЕЗОПАСНО:

    • " это то, что многие исполняемые файлы и интерпретаторы либо требовать — включая Windows PowerShell — при передаче строк снаружи — или, в случае Компиляторы Microsoft, поддержка в качестве альтернативы "" — в конечном итоге, однако, Целевая программа должна проанализировать список аргументов.
      • Пример: foo.exe "We had 3" of rain."
    • ОДНАКО, ИСПОЛЬЗОВАНИЕ " МОЖЕТ ПРИВЕСТИ К НЕЖЕЛАТЕЛЬНОМУ, ПРОИЗВОЛЬНОМУ ВЫПОЛНЕНИЮ КОМАНД и / или ПЕРЕПРАВКАМ ВВОДА / ВЫВОДА:
      • Следующие символы представляют этот риск: & | < >
      • Например, следующее приводит к непреднамеренному выполнению ver команда; см. ниже объяснение и следующий пункт для обходного пути:
        • foo.exe "3" of snow" "& ver."
    • Для того, чтобы получить Windows PowerShell, "" и "^"" надежные, но ограниченные альтернативы (см. раздел «Вызов интерфейса командной строки PowerShell …» ниже).
  • Если вы должны использовать "всего 3 безопасный подходы, которые, однако довольно громоздкий: Совет шляпы TS за его помощь.

    • Использование (возможно селективный) отложенное расширение переменной в вашем пакетном файле вы можете хранить буквальный " в переменная и ссылаться на эту переменную внутри "..." строка с использованием !var! синтаксис — увидеть Полезный ответ TS.

      • Вышеупомянутый подход, несмотря на его громоздкость, имеет то преимущество, что его можно применять методично и что это работает крепко, с любым входом.
    • Только с БУКВАЛЬНЫМИ строками — те, которые НЕ включают ПЕРЕМЕННЫЕ — вы получаете аналогичный методический подход: категорически ^-побег все cmd.exe метасимволы: " & | < > и — если вы также хотите подавить расширение переменных — %:
      foo.exe ^"3^" of snow^" ^"^& ver.^"

    • В противном случае вы должны сформулируйте свою строку на основе распознавания того, какие части строки cmd.exe считает не цитируется из-за неправильного толкования " в качестве закрывающих разделителей:

      • in буквальный части, содержащие метасимволы оболочки: ^-избегайте от них; используя приведенный выше пример, это & это должно быть ^-экранировано:
        foo.exe "3" of snow" "^& ver."

      • порциями с %...%ссылки на переменные стиля: гарантировать, что cmd.exe считает их частью "..." string и что значения переменных сами по себе не имеют встроенных несбалансированных кавычек — что даже не всегда возможно.

Для получения дополнительной информации читайте дальше.


проверка данных

Примечание: это основано на моих собственных экспериментах. Дай мне знать, если я ошибаюсь.

POSIX-подобные оболочки, такие как Bash on Unix-подобные системы токенизируйте список аргументов (строку) перед передачей аргументов в отдельности в целевую программу: среди других расширений они разбивают список аргументов на отдельные слова (разделение слов) и удаляют символы кавычек из полученных слов (удаление кавычек). Целевая программа вручается массив of отдельные аргументы, С синтаксический цитаты удалены.

В отличие от этого интерпретатор команд Windows, по-видимому, не токенизирует список аргументов и просто передает одинарной строка, содержащая все аргументы — включая кавычки. — в целевую программу.
Однако, некоторые предварительная обработка происходит до того, как единственная строка будет передана целевой программе: ^ escape chars. за пределами строк в двойных кавычках удаляются (они экранируются следующим символом), а ссылки на переменные (например, %USERNAME%) находятся интерполированное первый.

Таким образом, в отличие от Unix, целевая программа несет ответственность за синтаксический анализ, чтобы проанализировать строку аргументов и разбить ее на отдельные аргументы с удаленными кавычками. Таким образом, разные программы могут гипотетически требовать разные методы экранирования и нет единого механизма побега, который гарантированный работать со всеми программамиhttps://stackoverflow.com/a/4094897/45375 содержит отличную справочную информацию об анархии, которая представляет собой синтаксический анализ командной строки Windows.

На практике, " очень распространено, но НЕ БЕЗОПАСНО, как уже упоминалось выше:

С cmd.exe сам не признает " как спасся двойные кавычки, он может неверно истолковать более поздние токены в командной строке как не цитируется и потенциально интерпретировать их как команды и / или перенаправления ввода / вывода.
Вкратце: проблема проявляется, если какой-либо из следующих символов следует за открытие или неуравновешенный ": & | < >; например:

foo.exe "3" of snow" "& ver."

cmd.exe видит следующие токены, возникшие в результате неверной интерпретации " как обычная двойная кавычка:

  • "3"
  • of
  • snow" "
  • остальное: & ver.

С cmd.exe считает, что & ver. is не цитируется, он интерпретирует это как & (оператор последовательности команд), за которым следует имя команды для выполнения (ver.. игнорируется; ver отчеты cmd.exeинформация о версии).
Общий эффект:

  • Во-первых, foo.exe вызывается с первым 3 только токены.
  • Затем команда ver выполнен.

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

Многие компиляторы / интерпретаторы распознают ТОЛЬКО " — например, компилятор GNU C / C ++, Python, Perl, Ruby, даже собственная оболочка Microsoft Windows PowerShell при вызове из cmd.exe — и, кроме (с ограничениями) для Windows PowerShell с "", для них у этой проблемы нет простого решения.
По сути, вам нужно заранее знать, какие части вашей командной строки неверно интерпретируются как не цитируемые, и выборочно ^-экранировать все экземпляры & | < > в этих порциях.

С другой стороны, использование "" безопасно, но это к сожалению, поддерживается только исполняемыми файлами и пакетными файлами на основе компилятора Microsoft (в случае пакетных файлов, с особенностями, описанными выше), что примечательно исключает PowerShell — см. следующий раздел.


Вызов интерфейса командной строки PowerShell из cmd.exe или POSIX-подобные оболочки:

Примечание. См. Нижний раздел, чтобы узнать, как обрабатывается цитирование. внутри PowerShell.

При вызове снаружи — например, из cmd.exe, будь то из командной строки или командного файла:

  • PowerShell [Core] v6 + теперь правильно распознает "" (вдобавок к "), что одновременно безопасен в использовании и сохраняет пробелы.

    • pwsh -c " ""a & c"".length " не ломается и правильно уступает 6
  • Windows PowerShell (устаревшая версия, последняя версия которой — 5.1) признает только " а также в Windows """ и более надежный "" / "^"" (даже не смотря на внутренне PowerShell использует ` как escape-символ в строках, заключенных в двойные кавычки, а также принимает "" — см. нижний раздел):

призвание Windows PowerShell от cmd.exe / командный файл:

  • "" брейки, потому что он принципиально не поддерживается:

    • powershell -c " ""ab c"".length " -> ошибка «В строке отсутствует терминатор»
  • " и """ Работа в принципе, но не безопасный:

    • powershell -c " "ab c".length " работает по назначению: выводит 5 (Обратите внимание 2 пробелы)
    • Но это небезопасно, потому что cmd.exe метасимволы прерывают команду, если не экранированы:
      powershell -c " "a& c".length " брейки, из-за &, который нужно было бы экранировать как ^&
  • "" is безопасный, Но нормализовать внутренние пробелы, что может быть нежелательным:

    • powershell -c " ""a& c"".length " выходы 4(!), потому что 2 пробела нормированы на 1.
  • "^"" это лучший выбор для Windows PowerShell конкретно, где это безопасно и сохраняет пробелы, но с PowerShell Основные (в Windows) это то же самое, что "", то есть пробел —нормализующий. Кредит идет на Венрикс за открытие этого подхода.

    • powershell -c " "^""a& c"^"".length " работает: не ломается — несмотря на &и выходы 5, т. е. правильно сохраненные пробелы.

    • PowerShell Основные: pwsh -c " "^""a& c"^"".length " работает, но выходы 4т.е. нормализует пробелы, так как "" делает.

On Unix-подобные платформы (Linux, macOS), при звонке PowerShell [Ядро]CLI, pwshиз POSIX-подобной оболочки, такой как bash:

Ты должен использование ", который, однако, как безопасный, так и с сохранением пробелов:

$ pwsh -c " "a&  c|".length" # OK: 5

Связанная информация

  • ^ может использоваться только как escape-символ в не цитируется струны — внутри строк в двойных кавычках, ^ не является особенным и рассматривается как буквальное.

    • ПРЕДОСТЕРЕЖЕНИЕ: использование ^ в параметрах, переданных в call заявление нарушено (это относится к обоим видам использования call: вызов другого командного файла или двоичного файла и вызов подпрограммы в том же командном файле):
      • ^ экземпляры в двойные кавычки значения необъяснимо вдвое, изменение передаваемого значения: например, если переменная %v% содержит буквальное значение a^b, call :foo "%v%" правопреемники "a^^b"(!) к %1 (первый параметр) в подпрограмме :foo.
      • Без кавычек использование ^ с call is полностью сломан в этом ^ больше не может использоваться для экранирования специальных символовНапример, call foo.cmd a^&b тихо ломается (вместо передачи буквального a&b слишком foo.cmd, как и в случае без call) — foo.cmd никогда даже не вызывается (!), по крайней мере, в Windows 7.
  • Спасаясь от буквального % это особый случайк сожалению, который требует особого синтаксиса в зависимости от того, указана ли строка в командной строки против внутри командного файла; увидеть https://stackoverflow.com/a/31420292/45375

    • Вкратце: внутри командного файла используйте %%. В командной строке % невозможно избежать, но если вы поместите ^ в начале, конце или внутри имени переменной в не цитируется строка (например, echo %^foo%), вы можете предотвратить расширение переменных (интерполяцию); % экземпляры в командной строке, которые не являются частью ссылки на переменную, обрабатываются как литералы (например, 100%).
  • В общем, для безопасной работы со значениями переменных, которые могут содержать пробелы и специальные символы:

    • Назначение: окружать и то и другое имя переменной и значение в одинарной пара двойных кавычек; например, set "v=a & b" присваивает буквальное значение a & b изменять %v% (напротив, set v="a & b" сделает двойные кавычки частью значения). Буквальный побег % экземпляры как %% (работает только в пакетных файлах — см. выше).
    • Справка: Ссылки на переменные в двойных кавычках чтобы убедиться, что их значение не интерполируется; например, echo "%v%" не подчиняется стоимости %v% для интерполяции и печати "a & b" (но обратите внимание, что двойные кавычки тоже неизменно печатаются). Напротив, echo %v% проходит буквально a в echoинтерпретирует & как оператор последовательности команд, и поэтому пытается выполнить команду с именем b.
      Также обратите внимание на приведенное выше предостережение о повторном использовании ^ с call заявление.
    • Внешний программы обычно заботятся об удалении параметров, заключенных в двойные кавычки, но, как уже отмечалось, в пакетных файлах вы должны сделать это самостоятельно (например, %~1 чтобы удалить заключительные двойные кавычки из 1-го параметра) и, к сожалению, я не знаю прямого способа получить echo чтобы точно распечатать значение переменной без заключительные двойные кавычки.
      • Нил предложения a for-основанный обходной путь, который работает если значение не имеет встроенных двойных кавычек; например:
        set "var=^&')|;,%!"
        for /f "delims=" %%v in ("%var%") do echo %%~v
  • cmd.exe делает не признавать одинарной-Котировки как разделители строк — они рассматриваются как литералы и обычно не могут использоваться для разделения строк с внедренными пробелами; также следует, что токены, примыкающие к одинарным кавычкам, и любые токены между ними рассматриваются как некотируемые cmd.exe и интерпретируется соответственно.

    • Однако, учитывая, что целевые программы в конечном итоге выполняют собственный синтаксический анализ аргументов, некоторые программы, такие как Ruby, действительно распознают строки в одинарных кавычках даже в Windows; Напротив, исполняемые файлы C / C ++, Perl и Python делают не узнайте их.
      Однако даже если это поддерживается целевой программой, не рекомендуется использовать строки в одинарных кавычках, поскольку их содержимое не защищено от потенциально нежелательной интерпретации с помощью cmd.exe.

Цитировать из в PowerShell:

Windows PowerShell это гораздо более продвинутая оболочка, чем cmd.exe, и он уже много лет является частью Windows (и PowerShell Core перенесла PowerShell в macOS и Linux).

PowerShell работает стабильно внутренне в отношении цитирования:

  • внутри строк с двойными кавычками используйте `" or "" чтобы избежать двойных кавычек
  • внутри строк в одинарных кавычках используйте '' чтобы избежать одинарных кавычек

Это работает в командной строке PowerShell и при передаче параметров в сценарии PowerShell или функции из в PowerShell.

(Как обсуждалось выше, передача экранированных двойных кавычек в PowerShell снаружи требуется " или, что более надежно, "" — больше ничего не работает).

К сожалению, при вызове и, что лучший способ программы из PowerShell, вы столкнетесь с необходимостью учитывать и собственные правила цитирования PowerShell. и сбежать для цель программа:

Это проблемное поведение также обсуждается и резюмируется в этот ответ

двойной— цитаты внутри двойнойстроки в кавычках:

Рассмотрим строку "3`" of rain", который внутри PowerShell переводится как буквальный 3" of rain.

Если вы хотите передать эту строку внешней программе, вы должны применить экранирование целевой программы в дополнение к PowerShell; скажем, вы хотите передать строку программе C, которая ожидает, что встроенные двойные кавычки будут экранированы как ":

foo.exe "3`" of rain"

Обратите внимание, как и то и другое `" — чтобы сделать PowerShell счастливым — и что собой представляет — чтобы целевая программа была довольна — необходимо присутствовать.

Та же логика применяется к вызову командного файла, где "" необходимо использовать:

foo.bat "3`"`" of rain"

Напротив, встраивание одинарной-цитаты в двойнойстрока в кавычках не требует никакого побега.

Один— цитаты внутри одинарнойстроки в кавычках do не требовать дополнительно побег; рассмотреть возможность '2'' of snow', который является представлением PowerShell 2' of snow.

foo.exe '2'' of snow'
foo.bat '2'' of snow'

PowerShell переводит строки с одинарными кавычками в строки с двойными кавычками перед их передачей в целевую программу.

Однако, двойной— цитаты внутри одинарнойстроки в кавычках, которые не нуждаются в побеге для PowerShell, по-прежнему нужно убегать для целевая программа:

foo.exe '3" of rain'
foo.bat '3"" of rain'

PowerShell v3 представил магию --% вариант, Называется символ остановки анализа, который частично облегчает боль, пропуская что-нибудь после него. неинтерпретированный в целевую программу, за исключением cmd.exeссылки на переменные среды в стиле стиля (например, %USERNAME%), который Он расширенный; например:

foo.exe --% "3" of rain" -u %USERNAME%

Обратите внимание, как экранирование встроенного " as " только для целевой программы (а не для PowerShell как `") достаточно.

Однако такой подход:

  • не позволяет побег % символов, чтобы избежать раскрытия переменных среды.
  • исключающей направлять использование переменных и выражений PowerShell; вместо этого командная строка должна быть построена в строковой переменной на первом шаге, а затем вызвана с помощью Invoke-Expression через секунду.

Таким образом, несмотря на множество усовершенствований, PowerShell не упростил экранирование при вызове внешних программ. Однако в нем появилась поддержка строк в одинарных кавычках.

Интересно, возможно ли вообще в мире Windows когда-либо перейти на модель Unix, позволяющую оболочка сделайте всю токенизацию и удаление котировок предсказуемо, впереди, независимо от целевой программы, а затем вызовите целевую программу, передав полученные токены.

Имеется некое приложение командной строки (кто знает cryptcp). Этому приложению передается большое количество параметров. Один из параметров заключен в двойные кавычки. И внутри этого параметра есть значение также содержащее двойные кавычки (обратите внимание на значение параметра -dn — он как раз в двойных кавычках, а в самом значении есть O=ООО «Тестовая организация»)

cryptcp -creatrqst p20.der -provtype 75 -cont Petrov20 -dn «T=Руководитель,OID.1.2.840.113549.1.9.2=INN=0123456789/KPP=123456789/OGRN=0123456789123,CN=Петров Петр Петрович,OU=Тестовое подразделение,O=ООО «Тестовая организация»,L=Краснодар,S=23 Краснодарский край,C=RU,E=test@test.ru,ИНН=001234567890,ОГРН=0123456789123,СНИЛС=12345678901″ -certusage «1.2.643.1.1,1.2.643.1.2,1.2.643.1.3.1,1.2.643.1.4.5,1.2.643.1.5,1.2.643.1.6» -both -ku -provname «Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider»

Что уже попробовал:
-обрамление значения в ‘ или ` вместо двойных кавычек;
-экранирование двойных кавычек в O=ООО «Тестовая организация» символами , ^;
— замену O=ООО «Тестовая организация» на O=ООО «»Тестовая организация»»;
— замену » на x22 или x22 или ^x22;
— замену пробелов в значении на %20, чтобы все значение не заключать в двойные кавычки.

Прошу подсказать еще варианты.

Спасибо

В пакетном файле Windows, когда вы делаете следующее:

set myvar="c:my music & videos"

переменная myvar сохраняется с включенными кавычками. Честно говоря, я нахожу это очень глупым. Кавычки — это просто указать, где начинается и заканчивается строка, а не сохраняться как часть самого значения.
Как я могу предотвратить это?

Спасибо.

4b9b3361

Ответ 1

set "myvar=c:my music & videos"

Обратите внимание на начало цитат перед myvar. Это на самом деле так просто.
Боковое примечание: myvar не может быть отозван после этого, если он не заключен в кавычки, потому что и будет считан как разделитель команд, но он все равно будет работать как путь.

http://ss64.com/nt/set.html в разделе «Имена переменных могут включать пробелы»

Ответ 2

Это правильный способ сделать это:

set "myvar=c:my music & videos"

Кавычки не будут включены в значение переменной.

Ответ 3

Это зависит от того, как вы хотите использовать переменную. Если вы просто хотите использовать значение переменной без кавычек, вы можете использовать замедленное расширение и замену строки или команду for:

@echo OFF
SETLOCAL enabledelayedexpansion

set myvar="C:my music & videos"

В качестве состояний andynormancx необходимы кавычки, поскольку строка содержит &. Или вы можете избежать его с помощью ^, но я думаю, что цитаты немного чище.

Если вы используете замедленное расширение с заменой строки, вы получаете значение переменной без кавычек:

@echo !myvar:"=!
>>> C:my music & videos

Вы также можете использовать команду for:

for /f "tokens=* delims=" %%P in (%myvar%) do (
    @echo %%P
)
>>> C:my music & videos

Однако, если вы хотите использовать переменную в команде, вы должны использовать указанное значение или заключить значение переменной в кавычки:

  • Использование замены строк и замедленного расширения для использования значения переменной без кавычек, но используйте переменную в команде:

    @echo OFF
    SETLOCAL enabledelayedexpansion
    
    set myvar="C:my music & videos"
    md %myvar%
    @echo !myvar:"=! created.
    
  • Использование команды for для использования значения переменной без кавычек, но вам придется окружать переменную кавычками при ее использовании в командах:

    @echo OFF
    set myvar="C:my music & videos"
    
    for /f "tokens=* delims=" %%P in (%myvar%) do (
        md "%%P"
        @echo %%P created.
    )
    

Короче говоря, на самом деле нет чистого способа использовать путь или имя файла, содержащее встроенные пространства и/или & в пакетном файле.

Ответ 4

Использовать jscript.

Многие луны назад (т.е. около 8 лет дают или берут) Я работал над большим проектом С++/VB6, и у меня было несколько бит Batch Script, чтобы сделать части сборки.

Затем кто-то указал мне на Joel Test, я был особенно влюблен в пункт 2 и решил принести все мои маленькие скрипты сборки в один single build Script.,.

и это почти сломало мое сердце, заставив все эти маленькие скрипты работать вместе, на разных машинах, с немного разными настройками, боги, это было ужасно — в частности, установление переменных и передача параметров. Это было действительно хрупкое, малейшее дело сломало бы его и потребовало бы 30 минут настройки, чтобы снова идти.

В конце концов — я могу быть упрямым — Я забросил всю игру и за день переписал все это в JavaScript, запустив его из командной строки с CScript.

Я не оглядывался назад. Хотя в наши дни это MSBuild и Cruise Control, если мне нужно что-то даже немного задействовать с пакетом script, я использую jscript.

Ответ 5

Командный интерпретатор Windows позволяет использовать кавычки вокруг всей команды набора (действителен в каждой версии Windows NT от NT 4.0 до Windows 2012 R2)

Ваш script должен быть написан следующим образом:

@echo OFF

set "myvar=C:my music & videos"

Затем вы можете поместить кавычки вокруг переменных по мере необходимости.

Работа с приглашением CMD может казаться эзотерическим время от времени, но интерпретатор команд действительно ведет себя довольно твердо, подчиняясь его внутренней логике, вам просто нужно переосмыслить вещи.

Фактически команда set не требует, чтобы вы использовали кавычки вообще, но как то, как вы выполняете назначение переменной, так и способ использования кавычек не может вызвать лишние пробелы вокруг вашей переменной, когда вы отлаживаете script.

например. Оба нижеследующих являются технически допустимыми, но вы можете иметь конечные пробелы, поэтому это не очень хорошая практика:

set myvar=some text   
set myvar="some text" 

например. Оба из этих правил являются хорошими методами для установки переменных в интерпретаторе команд Windows, однако метод двойной кавычки превосходит:

set "myvar=Some text"
(set myvar=Some value)

Оба они не оставляют ничего для интерпретации, переменная будет иметь точно данные, которые вы ищете.

сильный текст Однако для ваших целей только цитируемый метод будет работать корректно, потому что вы используете зарезервированный символ

Таким образом, вы должны использовать:

set myvar="c:my music & videos"

Однако, несмотря на то, что переменная IS правильно настроена на эту строку, когда вы ECHO на sting, интерпретатор команд интерпретирует амперсанд, поскольку ключевое слово указывает, что следующий оператор следует.

SO, если вы хотите повторить строку из переменной, интерпретатору CMD все равно нужно сообщить ему текстовую строку или если вы не хотите, чтобы кавычки отображались, вам нужно выполнить одно из следующих действий:

эхо переменная WITH Quotes:

Echo."%myvar%"

эхо переменная WITHOUT Quotes:

Echo.%myvar:&=^&%
<nul SET /P="%myvar%"

В приведенных выше двух сценариях вы можете повторять строку без каких-либо кавычек. Пример ниже:

C:Admin>    Echo.%myvar:&=^&%
C:my music & videos

C:Admin>    <nul SET /P="%myvar%"
C:my music & videos
C:Admin>

Ответ 6

У вас должны быть кавычки, если текст, который вы устанавливаете, включает определенные символы, включая &. Если ваш текст не включал &, вам не нужны кавычки.

Например, если текст был просто «c:my music», вы могли бы сделать:

set myvar = c:my music

Но поскольку у вашего текста есть &, вам нужны кавычки.

Edit:

Или, как говорит Дэйв в своем ответе, вы можете избежать проблемных символов с помощью ^^^, но остерегайтесь этого подхода, поскольку & не единственный персонаж, которого вы нужно бежать. На практике гораздо проще придерживаться кавычек, а не избегать всех проблемных символов.

Ответ 7

Попробуйте использовать escape-символ ‘^’, например

set myvar=c:my music ^& videos

Вы будете осторожны при расширении myvar, потому что оболочка может не обрабатывать и как литерал. Если вышеописанное не работает, попробуйте также вставить каретку в строку:

set myvar=c:my music ^^^& videos

Перейти к содержимому раздела

Серый форум

разработка скриптов

Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.

Страницы 1

Чтобы отправить ответ, вы должны войти или зарегистрироваться

1 2013-07-05 23:49:59 (изменено: BlackOverlord, 2013-07-05 23:51:09)

  • BlackOverlord
  • Участник
  • Неактивен
  • Рейтинг : [0|0]

Тема: CMD/BAT: Как экранировать двойные кавычки?

Проблема такова: нужно запустить некий скрипт/программу и в качестве аргумента передать длинную строку, которая содержит любые символы (в том числе пробелы и двойные кавычки). Что делать с пробелами — понятно, но как быть с двойными кавычками? В линуксе они просто экранируются бэкслэшем, в винде — не работает, пробовал через ^ — не получается. Есть идеи?

2 Ответ от Rumata 2013-07-06 02:33:20

  • Rumata
  • Разработчик
  • Неактивен

Re: CMD/BAT: Как экранировать двойные кавычки?

Удваивайте каждую внутреннюю кавычку.

( 2 * b ) || ! ( 2 * b )

3 Ответ от wisgest 2013-07-06 22:12:24

  • wisgest
  • Разработчик
  • Неактивен

Re: CMD/BAT: Как экранировать двойные кавычки?

Насколько я знаю, единого правила на этот счёт нет. Может быть, кстати, и обратный слэш — для REG.EXE и удвоенные кавычки — для FIND.EXE.
При определённых условиях (кавычек в аргументе чётное число, между чётной и следующей за ней нечётной кавычкой нет пробелов; это позволяется вызываемым приложением) кавычки можно вообще не экранировать.
При передаче аргументов собственноручно разрабатываемым командным файлам хорошо воспользоваться советом Rumata — вышеуказанные условия соблюдаются автоматически, но при этом надо не забыть при разборе аргументов заменить удвоенные кавычки одним знаком.

Сообщения 3

Страницы 1

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Like this post? Please share to your friends:
  • Датчик расположения скачать бесплатно для windows 7
  • Двойной экран на windows 10 горячие клавиши
  • Датчик mi windows and door sensor
  • Двойной щелчок мыши вместо одного windows 10
  • Дата рядом с часами windows 10