PowerShell嵌套Here-String

时间:2016-10-19 09:47:20

标签: powershell escaping herestring

在脚本中放置以下内容将失败:

$MyString = @'
hello
@'
'@
bye
'@

write-host $MyString

返回的错误如下:

At C:\scripts\test.ps1:6 char:1
+ '@
+ ~~
The string is missing the terminator: '.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

使用反引号(重音符号)对嵌套的@''@进行前缀确实可以作为转义字符,但它也被视为文字,因此出现在{{1}的输出中}。

是否有正确的方法可以在单引号here-string中转义单引号here-string,而不会干扰输出?

NB:

我应该提到外部here-string的内容是动态填充的,内容由另一个程序提供给powershell脚本作为命令行参数。这并没有反映在示例代码中,因为我不想用我非常具体和有点小众的实现来解决这个问题。

外部here-string不太可能包含一个内部here-string(但它可能发生),因此我觉得有必要采取一些防御性编程以适应这种情况。

2 个答案:

答案 0 :(得分:2)

对于外部here-string:

使用双引号
$MyString = @"
hello
@'
'@
bye
"@

或内部here-string:

$MyString = @'
hello
@"
"@
bye
'@

答案 1 :(得分:0)

尝试使用ScriptBlock(用{}括起来)代替外部的Here-String。 它适用于原始示例:

$MyString = {
hello
@'
'@
bye
}
write-host $MyString

结果:

PS > $MyString = {
>> hello
>> @'
>> '@
>> bye
>> }
>> write-host $MyString
>>

hello
@'
'@
bye

PS >

请注意开头和结尾的多余空白行。如果您省略了{之后和}前的换行符,则可以避免使用它们。

如有必要,可以使用ToString()函数将ScriptBlock显式转换为String。

不确定该解决方法是否在任何用例中都有效,因为它看上去很干净,因为ScriptBlock无需解释即可获取所有内容,不会被花括号引起混淆,也不会对任何引号感兴趣。