PowerShell - “Write-Output” vs “return” in functions
我已经使用PowerShell多年了,我以为我对它的一些"古怪"行为有所了解,但是遇到了一个我无法理解的问题也不是...
的尾巴
我一直使用" return "从函数返回值,但是最近我想我可以看一下Write-Output作为替代方法。但是,PowerShell是PowerShell,我发现了似乎毫无意义的东西(至少对我而言):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function Invoke-X{ write-output @{"aaa" ="bbb" } }; function Invoke-Y{ return @{"aaa" ="bbb" } }; $x = Invoke-X; $y = Invoke-Y; write-host $x.GetType().FullName write-host $y.GetType().FullName write-host ($x -is [hashtable]) write-host ($y -is [hashtable]) write-host ($x -is [pscustomobject]) write-host ($y -is [pscustomobject]) |
输出:
1 2 3 4 5 6 | System.Collections.Hashtable System.Collections.Hashtable True True True False |
$ x和$ y(或\\'write-output \\'和\\'return \\')之间有什么区别,这意味着它们都是散列表,但其中只有一个'-是\\ a pscustomobject?除了明显检查我在变量中具有的每个哈希表是否也是pscustomobject之外,是否有一种通用的方法可以确定与代码的区别?
我的$ PSVersionTable如下所示,以防此行为特定于特定版本的PowerShell:
1 2 3 4 5 6 7 8 9 10 | Name Value ---- ----- PSVersion 5.1.16299.492 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.16299.492 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 |
干杯,
M
在某种程度上,
归结为:
-
隐式表达输出与cmdlet产生的输出;使用
return (无cmdlet调用)属于前一种类别,使用Write-Output 属于后者。 -
仅package在cmdlet生成的输出中的,包裹在输出对象中-大多数是不可见的-
[psobject] 实例。
1 2 3 4 5 | # Expression output: NO [psobject] wrapper: @{"aaa" ="bbb" } -is [psobject] # -> $False # Cmdlet-produced output: [psobject]-wrapped (Write-Output @{"aaa" ="bbb" }) -is [psobject] # -> $True |
请注意-令人惊讶的是-
(更令人困惑的是,有一个单独的
在大多数情况下,这种额外的
And is there a generalised way I can determine the difference from code, other than obviously checking whether every hashtable I have in a variable is also a pscustomobject
请注意,哈希表不是PS自定义对象-由于
要检测真实的PS自定义对象-使用
1 | $obj -is [System.Management.Automation.PSCustomObject] # NOT just [pscustomobject]! |
请注意,从Windows PowerShell v5.1 / PowerShell Core v6.1.0开始,将相关的
作为额外的
1 | (Write-Output @{"aaa" ="bbb" }) -is [hashtable] # $True |
即,尽管有package器,但
因此,有些矛盾的是,即使这些类型无关,在这种情况下,
这些差异没有充分的理由,它们以抽象的泄漏(实现)使我震惊:内部构造意外地从窗帘后面偷看。
以下GitHub问题讨论了这些行为:
-
对象有时会被
[psobject] 隐形包裹,有时会导致意外行为。 -
即使存在独特的
[System.Management.Automation.PSCustomObject] 类型,为什么[pscustomobject] 与[psobject] 相同? -
是否应将所有
[psobject] cmdlet参数都更改为[object] ? -
-as 运算符不能这样识别System.Management.Automation.PSCustomObject 实例。