How to handle $null in the pipeline

后端 未结 4 1006
北恋
北恋 2021-02-05 07:25

I often have the following situation in my PowerShell code: I have a function or property that returns a collection of objects, or $null. If you push the results in

相关标签:
4条回答
  • 2021-02-05 07:43

    Another possibility:

    $objects | Foreach-Object -Begin{If($_ -eq $null){continue}} -Process {do your stuff here}
    

    More info in about_Continue

    0 讨论(0)
  • 2021-02-05 07:45

    I don't think anyone likes the fact that both "foreach ($a in $null) {}" and "$null | foreach-object{}" iterate once. Unfortunately there is no other way to do it than the ways you have demonstrated. You could be pithier:

    $null | ?{$_} | % { ... }
    

    the ?{$_} is shorthand for where-object {$_ -ne $null} as $null evaluated as a boolean expression will be treated as $false

    I have a filter defined in my profile like this:

    filter Skip-Null { $_|?{ $_ } }
    

    Usage:

    $null | skip-null | foreach { ... }
    

    A filter is the same as a function except the default block is process {} not end {}.

    UPDATE: As of PowerShell 3.0, $null is no longer iterable as a collection. Yay!

    -Oisin

    0 讨论(0)
  • 2021-02-05 07:55

    A quick note to Keith's answer to complete it

    Personally, I would return nothing. It makes sense:

    PS> function Empty { if ('a' -eq 'b') { 'equal' } }
    PS> Empty | % { write-host result is $_ }
    

    But now you are in problems if you assign result from Empty to a variable:

    PS> $v = Empty
    PS> $v | % { write-host result is $_ }
    

    There is a little trick to make it work. Just wrap the result from Empty as a array like this:

    PS> $v = @(Empty)
    PS> $v | % { write-host result is $_ }
    PS> $v.GetType()
    IsPublic IsSerial Name      BaseType
    -------- -------- ----      --------
    True     True     Object[]  System.Array
    PS> $v.Length
    0
    
    0 讨论(0)
  • 2021-02-05 08:09

    If you can modify your function, have it return an empty collection/array instead of $null:

    PS> function Empty { $null }
    PS> Empty | %{'hi'}
    hi
    
    PS> function Empty { @() }
    PS> Empty | %{'hi'}
    

    Otherwise, go with what Oisin suggests although I would suggest a slight tweak:

    filter Skip-Null { $_|?{ $_ -ne $null } } 
    

    Otherwise this will also filter 0 and $false.

    Update 4-30-2012: This issue is fixed in PowerShell v3. V3 will not iterate over a scalar $null value.

    0 讨论(0)
提交回复
热议问题