Работа с Powershell NULL сравнение и поиск неизвестного значения


28 сентября 2019


Примеры работы с NULL в Powershell сравнение и проверка на неизвестное значение

Powershell NULL так же как и в большинстве языков обозначает пустое или неизвестное значение. Эту переменную используют для избежания ошибок, например когда мы должны быть уверены что делаем операцию с существующим значением. В других языка такое же значение несет None.

В отличие от других языков в Powershell null является переменной, обозначается как $null и хранит ссылку. 

Переменная без объявленного значения будет равна неизвестному:

$null -eq $somevar

Так же как и результат функции, которая возвращает пустое значение:

function Get-None {return (Get-Process '*notexist*')}
$null -eq (Get-None)

powershell nullВ зависимости от того где будет применяться проверка на null результат может быть разным.

 

Проверка в строках

Если мы используем переменную в строках в зависимости от остального текста у нас будет либо пустая строка или пропущенное слово (в случае ниже):

$val = $null
Write-Output "Print $val val"

 Такой результат является поводом экранировать переменные, когда вы пытаетесь вставить их в строки. Например если вы формируете логи и не проверяете каждое значение на NULL, то у вас может появится пустое не понятное значение. Для избежания таких ситуаций можно использовать такой подход:

$val = $null
$date = Get-Date
$error_log = "[$date] ErrorId [$val]"
Write-Output $error_log

Powershell None

 

Проверка при работе с числами

Мы можем использовать NULL и ожидать такое значение при работе с числами и не получать ошибок. В разных случаях результат будет разным:

$null -eq ($null * 7)
$null -eq (7 * $null)
$null * 7
7 * $null

Powershell сравнение null 

 

Работа с массивами и индексами

Если мы объявим такую переменную и попробуем вызвать элемент по индексу, то получим ошибку:

$arr = $null
$arr[1]
  • Не удается индексировать в массив
  • Cannot index into a null array

Но если мы объявим массив и вызовем несуществующий элемент по индексу, то этой ошибки не будет:

$arr = '1','2','3'
$arr[100] -eq $null

 Но в случаях с массивами мы можем проверять вхождение:

$arr = '1','2','3',$null
$null -in $arr

Проверка null в массивах

 

При работе с объектами

Аналогично строкам несуществующее свойство объекта тоже будет иметь неизвестное значение:

$path = Get-ChildItem
$null -eq $path.NotExist

 Если мы попробуем вызвать метод, то получим ошибку:

$null.GetType()
  • Невозможно вызвать метод для выражения со значением NULL
  • You cannot call a method on a null-valued expression

Для избежания таких ситуация нужно делать проверки заранее или использовать try catch.

Единственное свойство, которое можно использовать - это счетчик count:

$val = $null
$val.count
0

Исключением является использование Count в PSCustomObject. В Powershell 5.1 у такого объекта нет свойства count, а начиная с версии 6 оно есть:

$value = [PSCustomObject]@{Name='SoneObject'}
if ( $value.count -eq 1 ) {"PS 6.1"}

Powershell null 6.1

 

Проверки на существование значений в условиях

В примерах с числами были ситуации, где расстановка значений играла весомое значение. Верной практикой считается ставить проверяемое значение справа, а null слева. Вы можете попробовать угадать результат следующей команды:

$value = @( $null )
if ( $value -eq $null ) {'Значение $null'}
if ( $value -ne $null ) {'Значение не $null'}
if ( $null -ne $value ) {'Значение не $null 2'}

Проверка на null

Если бы мы не использовали третье условие, то результат был бы False и возможный скрипт бы не выполнился.

Операторы сравнения сильно зависят от контекста использования. В зависимости от того является ли левое значение скалярным (число или строка), или списком (массив, список и т.д.) у нас будут возвращаться разные значения. Для примера ситуация выше, но уже с числом вернет два True:

null powershell

Если мы пишем условия, то в Powershell, так же как и в других языка, не обязательно выполнять сравнение: 

$a = 1
if ($a) {'ok'}

Подобное условие на самом деле выполняет следующие операции:

if ( $null -ne $a -and
     $a -ne 0 -and
     $a -ne '' -and
     $a -ne $false )
    {
        'ok'
    }

Powershell null

В отличие от других языков в Powershell иногда можно преобразовывать $null в другие типы. Если такое преобразование будет в рамках скрипта, то они не будут равны $null:

[int]$int = $null
$int

[string]$str = $null
$str -eq ''

В других случаях у нас могут появиться ошибки:

  • Не удается преобразовать значение "" в тип "System.Boolean".
  • Не удается преобразовать значение в тип "System.DateTime".
[bool]$bool = $null
$bool

[datetime]$date = $null

powershell none

Для проверки пустой строки можно так же использовать метод .Net IsNullOrEmpty:

$null -eq ''
[string]::IsNullOrEmpty('')
[string]::IsNullOrEmpty('some')

Powershell пустая строка

 

Работа с конвейером и циклами

При работе с конвейером, вне зависимости от заданных параметром, всегда будет ошибка:

$null | Get-NetIPAddress
  • Get-NetIPAddress : Не удается проверить аргумент для параметра "AssociatedIPInterface". Аргумент имеет значение NULL. Укажите допусти мое значение аргумента, после чего повторите выполнение команды.
  • Get-NetIPAddress : Cannot validate argument on parameter 'AssociatedIPInterface'. The argument is null. Provide a valid value for the

Исключения, если мы будем использовать конвейер и цикл:

$null |% {Get-NetIPAddress}

При использовании в цикле c foreach все будет пропущено:

foreach ($node in $null){Write-Output 'ok'}

А с ForEach-Object ошибка:

ForEach-Object ($node -in $null){Write-Output 'ok'}

 

Перенаправление вывода

Аналогично nix системам в Powershell тоже можно перенаправлять вывод в "никуда". Такую команду можно выполнять в стиле Powershell:

New-Item -Type Directory -Path 'C:\Folder' | Out-Null 

 Можно назначить переменную, результат будет таким же:

$null = New-Item -Type Directory -Path 'C:\Folder'

 Или использовать стиль Linux:

New-Item -Type Directory -Path 'C:\Folder' > $null 

Либо так, в случаях с потоками:

* > $null
...

Теги: #powershell


Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.