powershell - for - microsoft management azure
Cómo manejar $ null en la tubería (4)
A menudo tengo la siguiente situación en mi código de PowerShell: tengo una función o propiedad que devuelve una colección de objetos, o $null
. Si inserta los resultados en la tubería, también maneja un elemento en la tubería si $null
es el único elemento.
Ejemplo:
$Project.Features | Foreach-Object { Write-Host "Feature name: $($_.Name)" }
Si no hay características ($ Project.Features devuelve $ null), verá una sola línea con "Nombre de la característica:".
Veo tres maneras de resolver esto:
if ($Project.Features -ne $null)
{
$Project.Features | Foreach-Object { Write-Host "Feature name: $($_.Name)" }
}
o
$Project.Features | Where-Object {$_ -ne $null) | Foreach-Object {
Write-Host "Feature name: $($_.Name)"
}
o
$Project.Features | Foreach-Object {
if ($_ -ne $null) {
Write-Host "Feature name: $($_.Name)" }
}
}
Pero, en realidad, no me gustan ninguno de estos enfoques, pero ¿cuál ve usted como el mejor enfoque?
No creo que a nadie le guste el hecho de que tanto "foreach ($ a en $ null) {}" como "$ null | foreach-object {}" se repitan una vez. Desafortunadamente, no hay otra manera de hacerlo que las formas en que lo has demostrado. Podrías estar más serio:
$null | ?{$_} | % { ... }
?{$_}
es una abreviatura de where-object {$_ -ne $null}
ya que $null
evaluado como una expresión booleana se tratará como $false
Tengo un filtro definido en mi perfil como este:
filter Skip-Null { $_|?{ $_ } }
Uso:
$null | skip-null | foreach { ... }
Un filtro es lo mismo que una función, excepto que el bloque predeterminado es el proceso {} no finaliza {}.
ACTUALIZACIÓN : A partir de PowerShell 3.0, $null
ya no es iterable como una colección. ¡Hurra!
-Oisin
Otra posibilidad:
$objects | Foreach-Object -Begin{If($_ -eq $null){continue}} -Process {do your stuff here}
Más información en about_Continue
Si puede modificar su función, haga que devuelva una colección / matriz vacía en lugar de $ null:
PS> function Empty { $null }
PS> Empty | %{''hi''}
hi
PS> function Empty { @() }
PS> Empty | %{''hi''}
De lo contrario, vaya con lo que sugiere Oisin, aunque sugeriría un ligero cambio:
filter Skip-Null { $_|?{ $_ -ne $null } }
De lo contrario, esto también filtrará 0
y $false
.
Actualización 4-30-2012: este problema se solucionó en PowerShell v3. V3 no itera sobre un valor $ null escalar.
Una nota rápida a la respuesta de Keith para completarlo.
Personalmente, yo no devolvería nada . Que tiene sentido:
PS> function Empty { if (''a'' -eq ''b'') { ''equal'' } }
PS> Empty | % { write-host result is $_ }
Pero ahora estás en problemas si asignas el resultado de Empty
a una variable:
PS> $v = Empty
PS> $v | % { write-host result is $_ }
Hay un pequeño truco para que funcione. Solo envuelve el resultado de Empty
como una matriz como esta:
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