【问题标题】:PowerShell null doesn't get pipedPowerShell null 没有通过管道传输
【发布时间】:2014-09-04 04:56:16
【问题描述】:

因此,您学会使用 PowerShell 避免的第一个陷阱是这个 foreach:

$null | foreach { "hello" }

将执行一次。然而,我试图向同事解释这个概念并且发生了以下事情:

PS> $a = 1..9 | ? {$_ -eq 10}
PS> $a | % { "hello" }
PS>

我试图了解以下情况,但 $a 似乎是 $null,简单明了。

PS> $a = 1..9 | ? {$_ -eq 10}
PS> $a -eq $null
True
PS> $a.gettype()
You cannot call a method on a null-valued expression.
At line:1 char:1
+ $a.gettype()
+ ~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

PS> $a | gm
gm : No object has been specified to the get-member cmdlet.
At line:1 char:6
+ $a | gm
+      ~~
    + CategoryInfo          : CloseError: (:) [Get-Member], InvalidOperationException
    + FullyQualifiedErrorId : NoObjectInGetMember,Microsoft.PowerShell.Commands.GetMemberCommand

PS> $a | % { "hello" }
PS> $null | % { "hello" }
hello
PS> 

是否存在两种不同“类型”的 null? $a 真的是一个因某种原因而被我混淆的数组吗?

【问题讨论】:

标签: powershell


【解决方案1】:

这方面的一些历史 -

给定PS > $a = 1..9 | ? {$_ -eq 10}

Powershell 2.0 行为

PS > $a | % { "hello" }
hello
PS > $null | % { "hello" }
hello

Powershell 3.0 行为 - “修复”变量为 null 时的问题,但内置 $null 仍会迭代

PS > $a | % { "hello" }
PS > $null | % { "hello" }
hello

在 3.0 的 ForEach-Object documentation 中,他们添加了这个 -

由于 Windows PowerShell 将 null 视为显式占位符,因此 ForEach-Object cmdlet 为 $null 生成一个值,就像它为 您通过管道传递给它的其他对象。

PS C:\> 1, 2, $null, 4 | ForEach-Object {"Hello"} 
Hello 
Hello
Hello
Hello

$null 的 about_automatic_variables 文档也针对 3.0 进行了更新。

Powershell 2.0 $null 文档

$NULL
   Contains a NULL or empty value. You can use this variable to
   represent NULL in commands and scripts instead of using the string
   "NULL". The string can be interpreted as TRUE if it is converted to a
   non-empty string or a non-zero integer.

Powershell 3.0 $null 文档

$NULL
       $null is an automatic variable that contains a NULL or empty value. You
       can use this variable to represent an absent or undefined value in commands
       and scripts.

       Windows PowerShell treats $null as an object with a value, that is, as an
       explicit placeholder, so you can use $null to represent an empty value in a
       series of values.  

       For example, when $null is included in a collection, it is counted as one of
       the objects.

           C:\PS> $a = ".dir", $null, ".pdf"
           C:\PS> $a.count
           3

       If you pipe the $null variable to the ForEach-Object cmdlet, it generates a
       value for $null, just as it does for the other objects.

           PS C:\ps-test> ".dir", "$null, ".pdf" | Foreach {"Hello"}
           Hello
           Hello
           Hello

       As a result, you cannot use $null to mean "no parameter value." A parameter
       value of $null overrides the default parameter value.

       However, because Windows PowerShell treats the $null variable as a placeholder,
       you can use it scripts like the following one, which would not work if $null
       were ignored.

           $calendar = @($null, $null, “Meeting”, $null, $null, “Team Lunch”, $null)
           $days = Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
           $currentDay = 0

           foreach($day in $calendar)
           {
               if($day –ne $null)
               {
                   "Appointment on $($days[$currentDay]): $day"
               }

               $currentDay++
           } 

           Appointment on Tuesday: Meeting
           Appointment on Friday: Team lunch

注意 - 他们还使 foreach 关键字的行为与 3.0 中的 ForEach-Object 相同(跳过 $null 值变量,但将 $null 内置值转换为可迭代值)但他们没有'不要像使用 ForEach-Obect 那样在文档中提及新行为。

【讨论】:

  • 我不明白...按照这个逻辑,$aosfjiuhf | % { "hello" } 不会也没有任何结果吗?
  • @Nacht 查看新答案
  • 谢谢,这确实有助于我更好地理解 3.0 中的变化。这听起来像是会破坏很多东西的东西,但这更有意义。但是我使用的是 2.0,所以它并没有真正回答我的问题。 Jason Shirk 上面评论中的答案似乎是导致我的问题的原因。 $null 比我想象的要复杂得多!
  • @Nacht 如果您在 2.0 上,您的问题示例不正确 - 在 2.0 中 $a | % { "hello" } 将返回一个“你好”
  • 我的错!这是我的问题。我忘了我之前在我的win7机器上安装了v3.0。对不起!
猜你喜欢
  • 2021-08-04
  • 1970-01-01
  • 2019-01-24
  • 2021-11-27
  • 2019-12-05
  • 2015-02-28
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
相关资源
最近更新 更多