管道中忽略了 Powershell 过滤器
Powershell filter ignored in pipeline
我正在编写一个 Chef 库,以便更轻松地编写用于在 Windows 服务器上管理 Microsoft MSMQ 资源的自定义资源。 Chef 使用 Powershell 5.1 与 Windows 交互。
如果我对 Get-MsmqQueue
的调用失败并且 returns $Null
,我想提出一个错误。为此,我创建了一个过滤器以在值无效时引发错误。如果我管道化一个 $Null
值,这似乎有效,但如果该值是从 Get-MsmqQueue
返回的并且是 $Null
,它就不起作用。
有人知道为什么第 5 行不会引发错误,即使值等于 $Null
吗?
#1 filter Test-Null{ if ($Null -ne $_) { $_ } else { Write-Error "object does not exist" }}
#2 $a = $Null
#3 $a | Test-Null | ConvertTo-Json # this raises an error
#4 $a = Get-MsmqQueue -Name DoesNotExist
#5 $a | Test-Null | ConvertTo-Json # this does NOT raise an error
#6 $Null -eq $a # this evaluates to $True
产生 no 输出的 cmdlet 实际上并不发出 $null
- 它(隐含地)发出 [System.Management.Automation.Internal.AutomationNull]::Value
单例 在表达式中表现得像 $null
,但在枚举上下文中这样因为管道枚举 nothing 并且因此不会通过管道发送任何内容 - 与 actual $null
值不同。
# True $null *is* sent through the pipeline.
PS> $var = $null; $var | ForEach-Object { 'here' }
here
# [System.Management.Automation.Internal.AutomationNull]::Value is *not*.
# `& {}` is a simple way to create this value.
PS> $var = & {}; $var | ForEach-Object { 'here' }
# !! No output
从 PowerShell 7.0 开始,[System.Management.Automation.Internal.AutomationNull]::Value
只能间接,使用晦涩的技术 例如:
# Only returns $true if $var contains
# [System.Management.Automation.Internal.AutomationNull]::Value
$null -eq $var -and @($var).Count -eq 0
缺乏可发现性是有问题的,通过启用以下内容来改善这种情况是 this GitHub proposal。
$var -is [AutomationNull] # WISHFUL THINKING as of PowerShell 7.0
另一种测试方法。这测试标准输出是否为非空,而不是退出代码。我不是在测试平等性。作业是副作用。
if (not ($a = Get-MsmqQueue -Name DoesNotExist)) {
Write-Error "object does not exist" }
我正在编写一个 Chef 库,以便更轻松地编写用于在 Windows 服务器上管理 Microsoft MSMQ 资源的自定义资源。 Chef 使用 Powershell 5.1 与 Windows 交互。
如果我对 Get-MsmqQueue
的调用失败并且 returns $Null
,我想提出一个错误。为此,我创建了一个过滤器以在值无效时引发错误。如果我管道化一个 $Null
值,这似乎有效,但如果该值是从 Get-MsmqQueue
返回的并且是 $Null
,它就不起作用。
有人知道为什么第 5 行不会引发错误,即使值等于 $Null
吗?
#1 filter Test-Null{ if ($Null -ne $_) { $_ } else { Write-Error "object does not exist" }}
#2 $a = $Null
#3 $a | Test-Null | ConvertTo-Json # this raises an error
#4 $a = Get-MsmqQueue -Name DoesNotExist
#5 $a | Test-Null | ConvertTo-Json # this does NOT raise an error
#6 $Null -eq $a # this evaluates to $True
产生 no 输出的 cmdlet 实际上并不发出 $null
- 它(隐含地)发出 [System.Management.Automation.Internal.AutomationNull]::Value
单例 在表达式中表现得像 $null
,但在枚举上下文中这样因为管道枚举 nothing 并且因此不会通过管道发送任何内容 - 与 actual $null
值不同。
# True $null *is* sent through the pipeline.
PS> $var = $null; $var | ForEach-Object { 'here' }
here
# [System.Management.Automation.Internal.AutomationNull]::Value is *not*.
# `& {}` is a simple way to create this value.
PS> $var = & {}; $var | ForEach-Object { 'here' }
# !! No output
从 PowerShell 7.0 开始,[System.Management.Automation.Internal.AutomationNull]::Value
只能间接,使用晦涩的技术 例如:
# Only returns $true if $var contains
# [System.Management.Automation.Internal.AutomationNull]::Value
$null -eq $var -and @($var).Count -eq 0
缺乏可发现性是有问题的,通过启用以下内容来改善这种情况是 this GitHub proposal。
$var -is [AutomationNull] # WISHFUL THINKING as of PowerShell 7.0
另一种测试方法。这测试标准输出是否为非空,而不是退出代码。我不是在测试平等性。作业是副作用。
if (not ($a = Get-MsmqQueue -Name DoesNotExist)) {
Write-Error "object does not exist" }