Короткая версия
Как передать аргумент, содержащий кавычки, в собственную команду из PowerShell?
Использовать одинарные кавычки вместо двойныхкавычки в строке аргумента:
<b>"</b>/p:Target=<b>'</b>Data Source=(local)\SQL;Integrated Security=True<b>'"</b>
→ /p:Target=<b>'</b>Data Source=(local)\SQL;Integrated Security=True<b>'</b>
Используйте обратную косую черту для двойных кавычек в строке аргумента * :
<b>'</b>/p:Target=<b>\"</b>Data Source=(local)\SQL;Integrated Security=True<b>\"'</b>
→ /p:Target=<b>"</b>Data Source=(local)\SQL;Integrated Security=True<b>"</b>
Если встроенные кавычки используются только для обработки аргумента как одной строки, а неБудучи обязательной частью параметра, можно использовать следующее:
Заключать в кавычки всю строку аргумента вместо вложения кавычек в аргумент:
<b>'</b>/p:Target=Data Source=(local)\SQL;Integrated Security=True<b>'</b>
→ /p:Target=Data Source=(local)\SQL;Integrated Security=True
Сбросить все специальные символы PowerShell с помощью обратных галочек ∗ (это можно сделать только как строковый аргумент):
/p:Target=<b>`"</b>Data Source=<b>`(</b>local<b>`)</b>\SQL<b>`;</b>Integrated Security=True<b>`"</b>
или /p:Target=Data<b>` </b>Source=<b>`(</b>local<b>`)</b>\SQL<b>`;</b>Integrated<b>` </b>Security=True
→ /p:Target=Data<b> </b>Source=<b>(</b>local<b>)</b>\SQL<b>;</b>Integrated<b> </b>Security=True
Пример полной командной строки (с использованием второй альтернативы):
PS> [string[]]$arguments = @(
'/target:Deploy',
'/p:UseSandboxSettings=False',
'/p:TargetDatabase=UpdatedTargetDatabase',
'/p:TargetConnectionString=\"Data Source=(local)\SQL;Integrate Security=True\"',
'C:\program files\MyProjectName.dbproj'
)
PS> ./echoargs $arguments
Arg 0 is </target:Deploy>
Arg 1 is </p:UseSandboxSettings=False>
Arg 2 is </p:TargetDatabase=UpdatedTargetDatabase>
Arg 3 is </p:TargetConnectionString="Data Source=(local)\SQL;Integrate Security=True">
Arg 4 is <C:\program files\MyProjectName.dbproj>
Длинная версия
Вызов собственных команд - это нечто, возникающее при переходе между устаревшей системой cmd и PowerShell (почти так же, как «разделение параметров запятыми»).Готча;).
Я попытался обобщить все, что я знаю по поводу вызова команд в PowerShell (v2 и v3) здесь, вместе со всеми примерами и ссылками, которые я могу собрать.
1) Непосредственный вызов собственных команд
1.1) В простейшем случае для исполняемого файла, расположенного в пути среды, команду можно вызвать напрямую , как вы бы назвали командлет PowerShell.
PS> Get-ItemProperty echoargs.exe -Name IsReadOnly
...
IsReadOnly : True
PS> attrib echoargs.exe
A R C:\Users\Emperor XLII\EchoArgs.exe
1.2) Вне пути среды, для команд в определенном каталоге (включая текущий), можно использовать полный или относительный путь к команде .Идея состоит в том, чтобы оператор явно объявил «Я хочу вызвать этот файл», вместо того, чтобы произвольный файл с таким же именем выполнялся вместо него ( см. Этот вопрос длябольше информации о безопасности PowerShell ).Неспособность использовать путь, когда он требуется, приведет к ошибке «термин не распознан».
PS> echoargs arg
The term 'echoargs' is not recognized as the name of a cmdlet, function, script file,
or operable program...
PS> ./echoargs arg
Arg 0 is <arg>
PS> C:\Windows\system32\attrib.exe echoargs.exe
A R C:\Users\Emperor XLII\EchoArgs.exe
1.3) Если путь содержит специальные символы, можно использовать оператор вызова или escape-символ .Например, исполняемый файл, начинающийся с цифры, или расположенный в каталоге с пробелом.
PS> $env:Path
...;C:\tools\;...
PS> Copy-Item EchoArgs.exe C:\tools\5pecialCharacter.exe
PS> 5pecialCharacter.exe special character
Bad numeric constant: 5.
PS> & 5pecialCharacter.exe special character
Arg 0 is <special>
Arg 1 is <character>
PS> `5pecialCharacter.exe escaped` character
Arg 0 is <escaped character>
PS> C:\Users\Emperor XLII\EchoArgs.exe path with spaces
The term 'C:\Users\Emperor' is not recognized as the name of a cmdlet, function,
script file, or operable program...
PS> & 'C:\Users\Emperor XLII\EchoArgs.exe' path with spaces
Arg 0 is <path>
Arg 1 is <with>
Arg 2 is <spaces>
PS> C:\Users\Emperor` XLII\EchoArgs.exe escaped` path with` spaces
Arg 0 is <escaped path>
Arg 1 is <with spaces>
2) Косвенный вызов собственных команд
2.1) Если вы не вводите команду в интерактивном режиме, а вместо этого храните путь в переменной, Оператор вызова также можно использовать для вызова команды, названной в переменной .
PS> $command = 'C:\Users\Emperor XLII\EchoArgs.exe'
PS> $command arg
Unexpected token 'arg' in expression or statement.
PS> & $command arg
Arg 0 is <arg>
2.2) Аргументы, передаваемые команде, также могут храниться в переменных. Аргументы в переменных могут передаваться по отдельности или в массиве. Для переменных, содержащих пробелы, PowerShell автоматически экранирует пробелы, так что собственная команда видит его как один аргумент.(Обратите внимание, что оператор вызова обрабатывает первое значение как команду, а остальные значения как аргументы; аргументы не должны объединяться с переменной команды.)
PS> $singleArg = 'single arg'
PS> $mushedCommand = "$command $singleArg"
PS> $mushedCommand
C:\Users\Emperor XLII\EchoArgs.exe single arg
PS> & $mushedCommand
The term 'C:\Users\Emperor XLII\EchoArgs.exe single arg' is not recognized as the
name of a cmdlet, function, script file, or operable program...
PS> & $command $singleArg
Arg 0 is <single arg>
PS> $multipleArgs = 'multiple','args'
PS> & $command $multipleArgs
Arg 0 is <multiple>
Arg 1 is <args>
2.3) Формат массива особенно полезен для построения динамического списка аргументов для собственной команды. Чтобы каждый аргумент распознавался как отдельный параметр, важно, чтобы аргументы сохранялись в переменной массива.и не просто слиты воедино в одну строку.(Обратите внимание, что общая аббревиатура $args
- это автоматическая переменная в PowerShell, которая может привести к тому, что значения, сохраненные в ней, будут перезаписаны; вместо этого лучше использовать описательное имя, например $msbuildArgs
, чтобы избежать конфликта имен.)
PS> $mungedArguments = 'initial argument'
PS> $mungedArguments += 'second argument'
PS> $mungedArguments += $(if( $someVariable ) { 'dynamic A' } else { 'dynamic B' })
PS> ./echoargs $mungedArguments
Arg 0 is <initial argumentsecond argumentdynamic B>
PS> $arrayArguments = @('initial argument')
PS> $arrayArguments += 'second argument'
PS> $arrayArguments += $(if( $someVariable ) { 'dynamic A' } else { 'dynamic B' })
PS> ./echoargs $arrayArguments
Arg 0 is <initial argument>
Arg 1 is <second argument>
Arg 2 is <dynamic B>
2.4) Кроме того, для сценариев, функций, командлетов и т. П. PowerShell v2 может отправлять именованные аргументы, содержащиеся в хеш-таблице, используя технику «splatting», не беспокоясь о порядке параметров. Это не работает с собственными командами, которые не участвуют в объектной модели PowerShell и могут обрабатывать только строковые значения.
PS> $cmdletArgs = @{ Path = 'EchoArgs.exe'; Name = 'IsReadOnly' }
PS> $cmdlet = 'Get-ItemProperty'
PS> & $cmdlet $cmdletArgs # hashtable object passed to cmdlet
Cannot find path 'C:\Users\Emperor XLII\System.Collections.Hashtable'...
PS> & $cmdlet @cmdletArgs # hashtable values passed to cmdlet
...
IsReadOnly : True
PS> ./echoargs @cmdletArgs
Arg 0 is <Name>
Arg 1 is <IsReadOnly>
Arg 2 is <Path>
Arg 3 is <EchoArgs.exe>
3) Вызов собственных команд со сложными аргументами
3.1) Для простых аргументов обычно достаточно автоматического экранирования, используемого для собственных команд. Однако для круглых скобок, знаков доллара, пробелов и т. Д. символов, используемых PowerShell, необходимо экранировать, чтобы они отправлялись как есть исходным командам без их интерпретации синтаксическим анализатором. Это можно сделать с помощью escape-символа обратного тика `
или путем помещения аргумента в строку в одинарных кавычках.
PS> ./echoargs money=$10.00
Arg 0 is <money=.00>
PS> ./echoargs money=`$10.00
Arg 0 is <money=$10.00>
PS> ./echoargs value=(spaces and parenthesis)
The term 'spaces' is not recognized as the name of a cmdlet, function, script file,
or operable program...
PS> ./echoargs 'value=(spaces and parenthesis)'
Arg 0 is <value=(spaces and parenthesis)>
3.2) К сожалению, это не так просто, когда используются двойные кавычки. В качестве части обработки аргументов для собственных команд процессор PowerShell пытается нормализовать все двойные кавычки в аргументе, чтобы содержимое аргумента, без кавычек, передавалось как отдельное значение собственной команде. Собственная обработка параметров команды происходит как отдельный шаг после синтаксического анализа, поэтому обычное экранирование не будет работать для двойных кавычек; можно использовать только одинарные кавычки или двойные кавычки с обратной косой чертой .
PS> ./echoargs value="double quotes"
Arg 0 is <value=double quotes>
PS> ./echoargs 'value="string double quotes"'
Arg 0 is <value=string>
Arg 1 is <double>
Arg 2 is <quotes>
PS> ./echoargs value=`"escaped double quotes`"
Arg 0 is <value=escaped double quotes>
PS> ./echoargs 'value=\"backslash escaped double quotes\"'
Arg 0 is <value="backslash escaped double quotes">
PS> ./echoargs value='single quotes'
Arg 0 is <value=single quotes>
PS> ./echoargs "value='string single quotes'"
Arg 0 is <value='string single quotes'>
PS> ./echoargs value=`'escaped` single` quotes`'
Arg 0 is <value='escaped single quotes'>
3.3) В PowerShell v3 добавлен новый символ остановки разбора --%
(см. about_Parsing
). При использовании перед сложными аргументами --%
будет передавать аргументы как есть, без разбора или расширения переменных, за исключением cmd-подобных %ENVIRONMENT_VARIABLE%
значений .
PS> ./echoargs User:"$env:UserName" "Hash"#555
Arg 0 is <User:Emperor XLII>
Arg 1 is <Hash>
PS> ./echoargs User: "$env:UserName" --% "Hash"#555
Arg 0 is <User:Emperor XLII>
Arg 1 is <Hash#555>
PS> ./echoargs --% User: "%USERNAME%" "Hash"#555
Arg 0 is <User:Emperor XLII>
Arg 1 is <Hash#555>
Это также можно использовать для разборки единственной строки, представляющей несколько аргументов, путем передачи символа остановки синтаксического анализа в строке & lowast; (хотя лучше всего не мунг аргументы в первую очередь).
PS> $user = 'User:"%USERNAME%"'
PS> $hash = 'Hash#' + $hashNumber
PS> $mungedArguments = $user,$hash -join ' '
PS> ./echoargs $mungedArguments
Arg 0 is <User:%USERNAME% Hash#555>
PS> ./echoargs --% $mungedArguments
Arg 0 is <$mungedArguments>
PS> ./echoargs '--%' $mungedArguments
Arg 0 is <User:Emperor XLII>
Arg 1 is <Hash#555>
4) Отладка собственных команд
Существует два ключевых инструмента для отладки аргументов, которые PowerShell передает собственным командам.
4.1) Первое - это EchoArgs.exe
, консольное приложение из PowerShell Community Extensions , которое просто записывает аргументы, переданные ему в угловых скобках (как показано в приведенных выше примерах).
4.2) Второй - это Trace-Command
, командлет, который может показать много деталей о том, как PowerShell обрабатывает конвейер. В частности, источник трассировки NativeCommandParameterBinder
покажет, что PowerShell получает и передает собственной команде.
PS> Trace-Command *NativeCommand* { ./echoargs value="double quotes" } -PSHost
DEBUG: NativeCommandParameterBinder : Raw argument string: "value=double quotes"
DEBUG: NativeCommandParameterBinder : Argument 0: value=double quotes
PS> Trace-Command *NativeCommand* { ./echoargs 'value="double quotes"' } -PSHost
DEBUG: NativeCommandParameterBinder : Raw argument string: "value="double quotes""
DEBUG: NativeCommandParameterBinder : Argument 0: value=double
DEBUG: NativeCommandParameterBinder : Argument 1: quotes
PS> Trace-Command *NativeCommand* { ./echoargs value=`"double quotes`" } -PSHost
DEBUG: NativeCommandParameterBinder : Raw argument string: value="double quotes"
DEBUG: NativeCommandParameterBinder : Argument 0: value=double quotes
PS> Trace-Command *NativeCommand* { ./echoargs 'value=\"double quotes\"' } -PSHost
DEBUG: NativeCommandParameterBinder : Raw argument string: "value=\"double quotes\""
DEBUG: NativeCommandParameterBinder : Argument 0: value="double quotes"
Другие ресурсы
Статьи
Вопросы
- 2013-09-11 - PowerShell выполняет внешнюю команду, не принимая параметр
- 2013-02-20 - Параметры с двойными кавычками неправильно передаются в блок скриптов с помощью ArgumentList
- 2013-01-02 - ОШИБКА: Описание = Неверный запрос
- 2012-09-18 - Как выполнить внешнюю программу с параметрами в PowerShell?
- 2012-09-10 - Вызов исполняемого файла (с параметрами) из сценария powershell
- 2012-08-16 - Как передать значение свойства, содержащее точку с запятой, в командной строке MSBuild при запуске из PowerShell?
- 2012-08-08 - Вызов сценария ruby из powershell
- 2012-08-01 - Скобки или кавычки, прерывающие команду powershell
- 2012-07-13 - Проблемы с использованием powershell для выполнения безопасного поиска источника по метке
- 2012-06-13 - Отсутствует аргумент -m при использовании svn в windows powershell
- 2012-06-01 - Аргумент командной строки Powershell с пробелами и фигурными скобками?
- 2012-04-18 - Разнесенные пути, msbuild и psake
- 2012-04-12 - Заставить Power shell игнорировать точки с запятой
- 2012-03-08 - Простой Powershell Msbuild с параметром fails
- 2012-02-10 - Цитировать безумие в Powershell
- 2012-01-18 - Powershell: запустить msiexec с динамически созданными параметрами
- 2012-01-18 - Синтаксис оператора вызова (&) PowerShell и двойные кавычки
- 2012-01-16 - PowerShell - передача вычисленных путей с пробелами
- 2012-01-09 - powershell: скрипт для запуска программы с параметрами?
- 2011-12-20 - Powershell - вызов icacls с включенными в параметры паратезами
- 2011-12-15 - Журнал Msbuild не работает при выполнениичерез powershell
- 2011-12-06 - Передача параметров в InstallUtil из Powershell
- 2011-11-23 - Выполнение exe с аргументами с использованиемPowershell
- 2011-11-08 - Powershell удаляет кавычки при запуске процесса
- 2011-09-16 - Команды, выполняемые в PowerShell с переменными в окружениив кавычках не получится.Почему?
- 2011-07-25 - Странно разбирать кавычки Powershell (включает краткий анализ разбора цитат в одном из ответов)
- 2011-07-15 - powershell убирает двойные кавычки из аргументов командной строки
- 2011-06-14 - В Powershell как выполнить произвольную собственную команду изстрока?
- 2011-06-03 - Вызов Powershell msbuild с вложенными кавычками
- 2011-05-13 - powershell - передача параметровexe
- 2011-03-02 - Почему этот сценарий PowerShell не может правильно выполнить эту внешнюю команду?
- 2011-01-09 - Выполнение файла EXE с использованием сценария powershell
- 2010-12-13 - Аргументы командной строки для exe
- 2010-10-08 - Что происходит с этой командной строкой PowerShell, цитируя /Escape?
- 2010-10-05 - Запуск exe-файла с использованием powershell из каталога с пробелами в нем
- 2010-08-28 - Выполнение команды, хранящейся в переменной, из Powershell
- 2010-08-17 - Как вызвать msdeploy из powershell, когда параметры имеют пробелы?
- 2010-04-12 - Как подавить кавычки в командах Powershell для исполняемых файлов
- 2010-01-26 - powershell отправляет несколько параметров внешней команде
- 2009-11-04 - Как запустить exe в powershell с параметрами с пробелами и кавычками
- 2009-03-16 - PowerShell - Start-Processи Cmdline Switches
- 2009-01-14 - Как избежать аргументов командной строки в Powershell?