Why do I need to escape the last single quote in this Powershell here-string?

1

0

According to Powershell "about quoting rules":

A here-string is a single-quoted or double-quoted string in which quotation marks are interpreted literally.

However the following here-string results in a TerminatorExpectedAtEndOfString exception in Powershell version 5.0 (build 10586, revision 117). In a Powershell version 2.0 it works as expected:

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

If I quote the last single quote with a backtick (`) the here-string works as expected in both version 2.0 and 5.0.

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

Why do I need to escape the last single quote in a here-string?

Bram

Posted 2016-11-22T14:14:35.133

Reputation: 582

1IMHO, it is a bug in PowerShell parser. When in statement parse mode, it first try to interpret first thing as BareWord string literal. And if it failed, then it produce error. You can workaround this by putting extra space: $herestr =@"... or $herestr= @"...; or by enclosing in parenthesis: ($herestr=@"..."@). – user364455 – 2016-11-22T17:11:35.993

@PetSerAl: thanks for the feedback. Do you know if this is known bug or should I report it? – Bram – 2016-11-24T09:54:52.483

I think your bug have the same root cause as this one.

– user364455 – 2016-11-24T10:34:46.850

@PetSerAl: thanks: I created an issue on github as well since it's not clear if the uservoice forum is still being used: https://github.com/PowerShell/PowerShell/issues/2780 . If you post the workarounds you listed as an answer I'll accept it. In the mean time I found that the Posh style guide recommends to use spaces before and after the equal signs so that seems like the right way to work around this bug.

– Bram – 2016-11-25T11:37:48.010

Answers

1

I believe it is a bug in PowerShell parser. It looks like when it in statement parse mode, it first try to interpret first thing as BareWord string literal. And if it failed, then it produce error. You can workaround this by putting extra space before or after equal sign:

$herestr =@"
'"'
"@

or

$herestr= @"
'"'
"@

Or by using parenthesis:

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

Note, as parenthesis is not assignment or increment/decrement, them will write result of expression into pipeline, unlike bare assignment expression, so you need to explicitly ignore it with [void] or any other method.

user364455

Posted 2016-11-22T14:14:35.133

Reputation: 2 679