tl; dr
Если вы вызываете другой экземпляр PowerShell из PowerShell , используйте блок сценариев ({ ... }
) для получения предсказуемого поведения:
Windows PowerShell:
powershell.exe { .\TestQuotes.ps1 -Config "A B C" }
PowerShell Core :
pwsh { .\TestQuotes.ps1 -Config "A B C" }
This заставит кавычки аргументов работать как положено - и даже возвратит объектов с точностью, близкой к типу, из вызова, потому что используется сериализация, аналогичная используемой для удаленного взаимодействия PowerShell.
Обратите внимание, однако, что это , а не опция при вызове из вне PowerShell , например, из cmd.exe
или bash
.
Ознакомьтесь с объяснением поведения, которое вы видели при отсутствии блока сценария.
PowerShell CLI (вызов powershell.exe
(Windows PowerShell) / pwsh.exe
(PowerShell Core ) поддерживает только один параметр, который принимает положениеional аргумент (т. е. значение, которому не предшествует имя параметра , например -Command
).
In Windows PowerShell, этот (подразумеваемый) параметр равен -Command
.
In PowerShell Core , это-File
.
- Значение по умолчанию пришлось изменить для поддержки использования интерфейса командной строки в Unix shebang lines .
Любые аргументы после Первый позиционный аргумент, если таковой имеется, считается:
в Windows PowerShell: часть фрагментаисходного кода PowerShell , переданного (подразумеваемому) параметру
-Command
.
в PowerShell Core : отдельные аргументы в передать как литералы в файл сценария , указанный в первом позиционном аргументе (подразумеваемый аргумент -File
).
Аргументы переданы -Command
-неявно или явно - пройти два раунда синтаксического анализа с помощью PowerShell, что может быть сложно:
В первом раунде,"..."
(двойные кавычки), заключающие отдельные аргументы: раздет .
- Если вы звоните из PowerShell , это относится даже к аргументам, которые были первоначально
'...'
- заключено (в одинарных кавычках), потому что за кулисами PowerShell повторно цитирует такие аргументы, чтобы использовать "..."
при вызове внешних программ (включая сам CLI PowerShell).
В втором раунде извлеченные аргументы объединяются с пробелами для формирования одиночная строка , то есть , затем интерпретируется как Исходный код PowerShell .
Применяется к вашему вызову,это означает, что и PowerShell .\TestQuotes.ps1 -Config "A B C"
и PowerShell .\TestQuotes.ps1 -Config 'A B C'
привели к тому, что PowerShell в конечном итоге проанализировал и выполнил следующуюкод понижения:
.\TestQuotes.ps1 -Config A B C
То есть из-за 2 раундов синтаксического анализа исходное цитирование было потерян , в результате чего три различных аргументов были полученыпередан , который объясняет ваш симптом.
Если вам пришлось заставить вашу команду работать без блока сценария , у вас есть две опции:
Использование -File
, которое применяется только один цикл анализа :
powershell.exe -File .\TestQuotes.ps1 -Config "A B C"
- То есть , кроме удаления
"..."
, результирующие аргументы обрабатываются как литералы - что, однако, равно обычно , что выхочу.
С (подразумевается) -Command
, применить дополнительный слой цитирования :
powershell.exe -Command .\TestQuotes.ps1 -Config '\"A B C\"'
Обратите внимание, что PowerShell требует "
символов. быть экранированным как \"
в аргументах, передаваемых его CLI , тогда как внутри PowerShell , `"
(или ""
) должны использоваться.