PowerShell, выполняющий функцию в блоке скрипта с помощью Start-Process, делает странные вещи с двойными кавычками
у меня есть сценарий PowerShell, который редактирует реестр, поэтому он должен работать как администратор. Для этого я запускаю новый процесс PowerShell из моего запущенного сценария PowerShell и передаю часть пути раздела реестра, используя блок сценария с функцией в нем. Когда я использую двойные кавычки в этой функции, PowerShell пытается интерпретировать их как команды, а не строку. Если я использую одинарные кавычки, то все работает нормально.
я создал немного урезанная пример сценария powershell, который воспроизводит проблему. Вот фрагмент:
$ScriptBlock = {
function Test
{
$status = "This is a string"
Write-Output $status
}
}
Start-Process -FilePath PowerShell -ArgumentList "-NoExit -NoProfile -ExecutionPolicy Bypass -Command & {$ScriptBlock Test}"
таким образом, в новом процессе PowerShell он сначала определит код в блоке скрипта, а затем вызовет метод теста, и он выдает эту ошибку:
This: термин "This" не распознается как имя командлета, функции, файла скрипта или выполняемой программы. Проверьте правильность имя или если путь был включен, проверьте правильность пути и пытаться снова.
поэтому он пытается рассматривать строку как запятую, как будто я только что набрал This is a string
на новую строку в мой сценарий.
если я изменю строку
$status = "This is a string"
to
$status = 'This is a string'
скрипт работает, как ожидалось, и просто выводит строку This is a string
.
еще одна странная проблема, которую я заметил, что если я не использую переменную и просто использовать:
Write-Output "This is a string"
затем он выводит каждое слово на отдельном строку:
этой
и
a
строка
но если я использую одинарные кавычки, как это:
Write-Output 'This is a string'
затем он выводит все предложение в одну строку, как ожидалось.
кто-нибудь знает, почему PowerShell ведет себя странно в этих ситуациях?
ответ
так как tessellatingheckler упоминает, решение-это обернуть что-нибудь то есть двойные кавычки в двойные кавычки, одинарные кавычки, или вы можете использовать скобки.
Итак, в моем примере вы бы изменили:
$status = "This is a string"
для этого:
$status = """This is a string"""
или такой:
$status = '"This is a string"'
или такой:
$status = {"This is a string"}
если вы хотите оценить переменную в своей строке, хотя (т. е. см. значение переменной), то вам нужно пойти с методом двойных двойных кавычек:
$status = """This is a string that evaluates $someVariable"""
все еще не уверен, что это ошибка или По дизайну, но, по крайней мере, у нас есть обходной путь, так как это устраняет обе проблемы, которые я описал выше.
1 ответов
если я изменю скрипт
-Command $ScriptBlock
запустите его и откройте новое окно оболочки, затем запустите
gci function:test | fl
чтобы увидеть определение функции в новом окне, показан код
$status = This is a string
С тем же тестом на одинарной версии цитаты он показывает
$status = 'This is a string'
так это потерять кавычки. Побег их с двойными кавычками
$status = """This is a string"""
и они проходят нормально. Также, хотя scriptblocks-это скомпилированный код, он мне кажется, что они встроены в текст, если вы развернете их в строку:
> $s = { "hello" }
> "---$s---"
---"hello"---
поэтому я думаю, что вы попали в такую проблему цитирования:PowerShell удаляет двойные кавычки из аргументов командной строки и ответ Droj в частности, говоря: "странная вещь о отправке параметров во внешние программы заключается в том, что существует дополнительный уровень оценки котировок. Я не знаю, является ли это ошибкой, но я предполагаю, что это не будет изменено, потому что поведение такое же, когда вы используете Start-Process и передаете аргументы.".
PowerShell расширяет блок сценария в виде строки в вашу команду, затем эти одинарные кавычки вокруг строки переинтерпретируются как параметры кавычек и удаляются где-то в вызове. Это либо известная проблема, либо ошибка, либо по дизайну, в зависимости от того, как Вы читаете эту связанную статью connect.