我有以下PowerShell功能:
function Get-Devices {
[CmdletBinding()]
param(
[Parameter(Mandatory=$False, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True, ParameterSetName='Code')]
[String[]]$Codes
)
foreach ($Code in $Codes){write-output $Code}
}
虽然我这样称呼:
Get-Devices -Code 92D,88L
它产生了以下输出:
92 88
注意,最后一个字符D和字符L被剥离。如果我将值括在引号中,我可以使它工作。此外,以下所有内容都将按预期工作:
Get-Devices -Code D92,L88
Get-Devices -Code 92E,88F
Get-Devices -Code 34G,12Z
Get-Devices -Code“92D”,“88L”
特别注意上面的第二行。只有D
和L
足以给我带来麻烦。
是什么导致特定D和L被剥离掉每个值的末尾?我真的不想强迫人们为所有值添加周围的引号只是为了避免这个特定的问题。迫使Powershell从每个值的末尾剥离D
或L
的最简单方法是什么,而不需要这些值的周围引号?
我已尝试将输入参数类型更改为:[Array[]]$Codes
。这对行为没有任何影响。我还确认,在通过上述循环处理时,所有值都被视为字符串类型。任何帮助避免这种行为将不胜感激!
唯一的好消息是,这一小段代码和相应的奇怪行为很容易重现......
答案 0 :(得分:4)
要了解这里发生了什么,请记住Powershell与.Net有密切关系。看看用于在C#中声明数字文字的文档,以获取线索:
我们可以通过查看PowerShell language specification * :
来获得更具体的信息l
,kb
,mb
,gb
,tb
,和pb
。d
。您会在此处看到有几个后缀(包括D
和L
)来指示您正在使用的特定类型的数字。我愿意打赌所有其他后缀会给你带来同样的问题。如果我是对的,我也会回过头来仔细看看这个断言:
我还确认,当通过上述循环处理时,所有值都被视为字符串类型。
即使你的代码看起来也是如此。但是,在代码之前,首先将这些值解释为数字,然后将其转换为字符串。不幸的是,在这种情况下,它可能就是shell本身,这意味着除了需要引用之外,你无法对这个问题做任何事情:(
* 通过this question.
找到答案 1 :(得分:1)
非常有趣。我不知道这一点,也找不到任何文件说明,但在论证语境中(见Get-Help about_Parsing
),D
和L
似乎被解释为数字是否为被视为[decimal]
或[long]
。
请参阅:
PS C:\> $ExecutionContext.InvokeCommand.ExpandString(2.74D)
2.74
PS C:\> $ExecutionContext.InvokeCommand.ExpandString(2.74L)
3
Param
块本身无法做任何事情 - 解析器会解释D
和L
,即。按下Enter后的步骤,但之前将参数传递给函数