Почему я должен избегать последней одинарной кавычки в этой строке Powershell?

489
Bram

Согласно Powershell " о правилах цитирования ":

Здесь строка - это строка в одинарных или двойных кавычках, в которой кавычки интерпретируются буквально.

Однако следующая строка приводит к исключению TerminatorExpectedAtEndOfString в Powershell версии 5.0 (сборка 10586, редакция 117). В версии Powershell 2.0 он работает как положено:

$herestr=@" '"' "@ Write-Host $herestr 

Если я процитирую последнюю одинарную кавычку с обратным символом (`), строка здесь работает как ожидается, как в версии 2.0, так и в 5.0.

$herestr=@" '"`' "@ Write-Host $herestr 

Почему мне нужно экранировать последнюю одинарную кавычку в строке здесь?

1
ИМХО, это ошибка в анализаторе PowerShell. В режиме синтаксического анализа оператор сначала пытается интерпретировать как строковый литерал `BareWord`. И если это не удалось, то это приведет к ошибке. Вы можете обойти это, поставив дополнительный пробел: `$ herestr = @" ... `или` $ herestr = @ "...`; или заключив в скобки: `($ herestr = @" ... "@)`. PetSerAl 7 лет назад 1
@PetSerAl: спасибо за отзыв. Вы знаете, если это известная ошибка или я должен сообщить об этом? Bram 7 лет назад 0
Я думаю, что ваша ошибка имеет ту же основную причину, что и [эта] (https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/12531978-bug-in-variable-assignment-parser). PetSerAl 7 лет назад 0
@PetSerAl: спасибо: я также создал проблему на github, так как неясно, используется ли форум uservoice: https://github.com/PowerShell/PowerShell/issues/2780. Если вы опубликуете обходные пути, которые вы указали в качестве ответа, я приму это. В то же время я обнаружил, что руководство по стилю Posh рекомендует использовать пробелы до и после знаков равенства, так что это кажется правильным способом обойти эту ошибку. Bram 7 лет назад 0

1 ответ на вопрос

1
PetSerAl

Я считаю, что это ошибка в анализаторе PowerShell. Похоже, что когда он находится в режиме разбора операторов, он сначала пытается интерпретировать BareWordстроковый литерал. И если это не удалось, то это приведет к ошибке. Вы можете обойти это, поставив дополнительное пространство перед или после знака равенства:

$herestr =@" '"' "@ 

или же

$herestr= @" '"' "@ 

Или с помощью круглых скобок:

[void]($herestr=@" '"' "@) 

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