【问题标题】:Writing $null to Powershell Output Stream将 $null 写入 Powershell 输出流
【发布时间】:2016-02-11 14:55:42
【问题描述】:

我们的项目中有用于在数据库中查找数据的 powershell cmdlet。如果未找到数据,则 cmdlet 将 $null 写入输出流,如下所示:

Write-Output $null

或者,更准确地说,因为 cmdlet 是用 C# 实现的:

WriteOutput(null)

我发现这会导致一些与其他地方(包括内置 cmdlet)所采用的约定非常相反的行为。

是否有任何指南/规则,尤其是来自 Microsoft 的,讨论这个问题?我需要帮助更好地解释为什么这是一个坏主意,或者确信将 $null 写入输出流是一种好的做法。以下是我看到的结果行为的一些细节:

如果将结果通过管道传输到另一个 cmdlet,则该 cmdlet 会执行,尽管未找到任何结果且管道变量 ($_) 为 $null。这意味着我必须为 $null 添加检查。

Find-DbRecord -Id 3 | For-Each { if ($_ -ne $null) { <do something with $_> }}

同样,如果我想获取找到的记录数组,并确保它是一个数组,我可能会执行以下操作:

$recsFound = @(Find-DbRecord -Category XYZ)
foreach ($record in $recsFound)
{
    $record.Name = "Something New"
    $record.Update()
}

我见过的约定,这应该没有问题。如果没有找到记录,则不会执行 foreach 循环。由于 Find cmdlet 将 null 写入输出,因此 $recsFound 变量设置为一个数组,其中一项为 $null。现在我需要检查数组中的每个项目是否有 $null 这会使我的代码混乱。

【问题讨论】:

标签: powershell


【解决方案1】:

$null 不是无效的。如果您不希望管道中有空值,请首先不要将空值写入管道,或者使用如下过滤器将它们从管道中删除:

... | Where-Object { $_ -ne $null } | ...

根据您希望通过过滤器允许的内容,您可以将其简化为:

... | Where-Object { $_ } | ...

或(使用Where-Object 的别名?):

... | ? { $_ } | ...

这将删除 PowerShell 解释为 $false 的所有值($null、0、空字符串、空数组等)。

【讨论】:

  • 我同意可以这样做。我正在寻找的是一种或另一种方式的理由,在 Find 或什至 Get 的上下文中,其想法是找到任何结果,如果没有找到结果,为什么要在输出中写入 $null 。它实际上应该是一个空数组。这很容易通过不向管道写入任何内容来实现。
  • 我只能给你我个人的看法,那就是:除非你有结果,否则不要写。
  • 这也是我的观点,尽管我的目标是从大型社区或专门从 Microsoft 中找到指南或规则。或者一些我没有想到的理由可能有助于说服其他人我的方法更好。
猜你喜欢
  • 2021-05-13
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 2022-10-08
  • 2017-11-13
相关资源
最近更新 更多