PowerShell的空没有得到管道

问题描述:

所以你要学会避免与PowerShell中的第一个缺陷之一是,这的foreach:PowerShell的空没有得到管道

$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真的是一个数组,因为某些原因而被我混淆了吗?

+0

我一直认为'GetType'是找出变量类型的最可靠方法,忽略了脚本语言的模糊性。我一定是错的? – Nacht 2014-09-04 04:58:10

+0

仅供参考这不是从PS V3更真实 – 2014-09-04 07:03:59

+0

在这里看到一个相关的问题:http://stackoverflow.com/questions/4356758/how-to-handle-null-in-the-pipeline – 2014-09-04 07:15:43

一些历史上的这一点 -

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

PowerShell 2.0中的行为

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

PowerShell的3.0的行为 - “固定” 的问题时,变量为空,但内置$空依旧iterates

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

ForEach-Object documentation在3.0它们加入这个 -

由于Windows PowerShell将null作为一个明确的占位符,该 的ForEach对象cmdlet生成$空值,就像它对于其他 对象,你管吧。

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

为$空的参阅about_Automatic_Variables文档也被更新为3.0。

PowerShell 2.0中$空文档

$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 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关键字行为相同的foreach对象在3.0(跳过$空但将内置的$ null转换为可迭代的值),但他们没有提到文档中的新行为,就像他们对ForEach-Obect所做的那样。

+0

我不明白...按照这个逻辑,不会'$ aosfjiuhf | %{“hello”}'不会产生任何结果? – Nacht 2014-09-04 11:35:57

+0

@游艇签出新的答案 – 2014-09-04 23:51:45

+0

谢谢,这确实帮助我理解3.0中的变化好一点。这听起来像是会打破很多东西的东西,但这更有意义。然而,我使用2.0,所以它并没有真正回答我的问题。 Jason Shirk上面评论中的答案似乎是导致我的问题的原因。 $ nulls比我想象的要复杂得多! – Nacht 2014-09-05 04:41:23