PowerShell字符串格式:为什么冒号字符导致我的变量值为空?

Kev*_*han 28 powershell

我正在研究下一个WinRM和PowerShell 3会发生什么,我正在查看突破性变化列表,看到了我以前从未见过的东西.

这个例子是:

$server = "msp42"
$status = "online"
"$server: $status"
Run Code Online (Sandbox Code Playgroud)

结果输出是:

线上

好吧,我以前从未遇到过这种情况,也不知道为什么结肠会引起问题.文档中建议的解决方案是放置一个空格(因为然后更改输出,这是愚蠢的):

"$server : $status"
Run Code Online (Sandbox Code Playgroud)

另一个建议是使用这种格式(对我来说是新的!):

"${server}: $status"
Run Code Online (Sandbox Code Playgroud)

最后的建议是做一个我熟悉并且一直使用的表达式:

"$($server): $status"
Run Code Online (Sandbox Code Playgroud)

所以,我向你提出的问题PowerShell专家有:

  1. 这个结肠怎么了?它什么?

  2. 什么是${variable}语法?是严格处理结肠还是有一些整洁的功能?

Joe*_*oey 44

冒号是变量名称的有效字符,例如in $Env:PATH等.

您也可以使用以下选项

$server`: $status
Run Code Online (Sandbox Code Playgroud)

或者,在某些情况下,格式字符串更具可读性:

'{0}: {1}' -f $server, $status
Run Code Online (Sandbox Code Playgroud)

回到结肠.对于与PSDrive上的项目对应的变量名称,有一种特殊情况:

$Env:Foo           # equivalent to the contents of Env:\Foo
$Function:C:       # equivalent to the contents of Function:\C:
${C:\autoexec.bat} # ... you get the picture
Run Code Online (Sandbox Code Playgroud)

${}存在的语法是能够指定变量名称,否则这些变量名称将使用为语法的其他部分保留的字符.您可以@在标识符前面看到它与C#相似(但更强大).请参阅上面\的变量名称中使用a ,因为它$Drive:Item仅适用于驱动器上的当前容器(或非分层的容器,如Env,AliasFunction).

另一个例子,变量名通常是无效的语法:

PS> $+
The term '$+' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ $+
+ ~~
    + CategoryInfo          : ObjectNotFound: ($+:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS> ${+} = 5
PS> ${+}
5
PS> Get-Variable +

Name                           Value
----                           -----
+                              5
Run Code Online (Sandbox Code Playgroud)


小智 9

前几天在Windows PowerShell脚本中惹恼了我.假设你必须变量$ user和$ machine,并且想要打印一个字符串,其值都用冒号(':')分隔.

您显然可以使用字符串连接来执行此操作:

$user = 'tomasr' 
$machine = 'arcano' 

write ($user + ':' + $machine)
Run Code Online (Sandbox Code Playgroud)

这有效,但PowerShell不支持那种漂亮的字符串插值功能吗?为什么,是的呢!那么我们为什么不像这样重写它:

write "$user:$machine"
Run Code Online (Sandbox Code Playgroud)

可是等等!如果你运行最后一行,你得到的只是$ machine变量的值... $ user去了哪里?

答案是冒号在PowerShell变量名中有特殊含义:它用于将变量与特定范围或命名空间相关联.PowerShell定义了一些范围,例如script和global; 例如,全局变量可能被命名为$ global:var.

但是我们还没有看到其他地方的语法吗?当然,$ env:PATH怎么样?一样; 除了这里env本身不是一个范围,而是一个PSDrive.因此':'之前的部分可以是PS定义的实际范围,也可以是PSDrive.哎呀,你甚至可以尝试"$ {c:autoexec.bat}"之类的东西,看看神奇的事情发生了!

所以我们的字符串插值的问题是,当PowerShell看到时"$user:$machine",它希望找到名为'user'的范围/ psdrive,并期望变量名称跟随':',但'$'无效,'user'也不是范围或PSDrive,这使PowerShell有点困惑.但是因为他太绅士了,所以他尽可能地把它修好,并且忽略了到目前为止所做的一切,只是抛弃了机器而没有抱怨.对他很好,但是如果你没想到的话,它真的会让你失望!

我们可以避免这个吗?是的,我们可以通过使用"{}"简单地为PowerShell分隔变量名称,如下所示:

write "${user}:$machine"
Run Code Online (Sandbox Code Playgroud)

Bruce Payette的优秀Windows PowerShell in Action的第141页第5.8节介绍了PowerShell中的变量主题,并为我提供了解决此问题的线索.

  • 请在适当的时候注明信用。这取自https://winterdom.com/2008/02/20/watchoutforinpowershell。您直接偷了它,甚至没有更改示例代码中的tomas rarcano(写此代码的人的名字)。 (7认同)