Лично я избегаю использования «\» для экранирования вещей в PowerShell, потому что технически это не экранирующий символ оболочки. Я получил непредсказуемые результаты с ним. В строках с двойными кавычками вы можете использовать ""
, чтобы получить встроенную двойную кавычку, или экранировать ее обратной галочкой:
PS C:\Users\Droj> "string ""with`" quotes"
string "with" quotes
То же самое касается одинарных кавычек:
PS C:\Users\Droj> 'string ''with'' quotes'
string 'with' quotes
Странная вещь при отправке параметров во внешние программы заключается в том, что существует дополнительный уровень оценки котировок. Я не знаю, является ли это ошибкой, но я предполагаю, что она не изменится, потому что поведение при запуске Start-Process и передаче аргументов одинаково. Start-Process принимает массив для аргументов, что делает вещи более понятными с точки зрения того, сколько аргументов фактически отправляется, но эти аргументы, кажется, оцениваются в дополнительное время.
Итак, если у меня есть массив, я могу установить в значениях arg встроенные кавычки:
PS C:\cygwin\home\Droj> $aa = 'arg="foo"', 'arg=""""bar""""'
PS C:\cygwin\home\Droj> echo $aa
arg="foo"
arg=""""bar""""
Аргумента 'bar' достаточно, чтобы покрыть дополнительную скрытую оценку. Это как если бы я отправил это значение командлету в двойных кавычках, а затем снова отправил этот результат в двойных кавычках:
PS C:\cygwin\home\Droj> echo "arg=""""bar""""" # level one
arg=""bar""
PS C:\cygwin\home\Droj> echo "arg=""bar""" # hidden level
arg="bar"
Можно ожидать, что эти аргументы будут передаваться во внешние команды как есть, как и в командлеты типа 'echo' / 'write-output', но это не так, из-за этого скрытого уровня:
PS C:\cygwin\home\Droj> $aa = 'arg="foo"', 'arg=""""bar""""'
PS C:\cygwin\home\Droj> start c:\cygwin\bin\echo $aa -nonew -wait
arg=foo arg="bar"
Я не знаю точную причину этого, но поведение таково, как будто есть еще один, недокументированный шаг, предпринимаемый под крышками, который повторно анализирует строки. Например, я получаю тот же результат, если отправляю массив в командлет, но добавляю уровень синтаксического анализа, выполняя его через invoke-expression
:
PS C:\cygwin\home\Droj> $aa = 'arg="foo"', 'arg=""""bar""""'
PS C:\cygwin\home\Droj> iex "echo $aa"
arg=foo
arg="bar"
... именно это я и получаю, отправляя эти аргументы моему внешнему cygwin 'echo.exe':
PS C:\cygwin\home\Droj> c:\cygwin\bin\echo 'arg="foo"' 'arg=""""bar""""'
arg=foo arg="bar"