Powershell 的设计非常松散,而且存在很多反人类的设计,一不小心就会出现预料以外的错误。
第一点,$Null 在 Powershell 中不是一种数据类型,而是一个对象,这个对象的值是 NULL,但在 Powershell 中你又不能使用 NULL ,因为 NULL 不是一个数据类型也不是类名。
第二点,$Null 的任何属性值都是 $Null,唯一例外的是 Count,它的值是 0,这和上面这一点又互相矛盾了,既然 $Null 是一个包含一个值为 NULL 的集合,它的元素个数为什么是 0 而不是 1 呢?
第三点,如果将 $Null 传递给 ForEach-Object,ForEach-Object 会执行。- $Null | ForEach-Object {
- Write-Host "Hello, Wu Xiancheng"
- }
复制代码- ForEach-Object -InputObject $Null {
- Write-Host "Hello, Wu Xiancheng"
- }
复制代码 以上两段代码都会输出
而使用 ForEach 或 For 循环,却不会有任何执行。
- ForEach ($Item in $Null) {
- Write-Host "Hello, Wu Xiancheng"
- }
复制代码- For ($I=0; $I -lt $Null.Count; $I++) {
- Write-Host "Hello, Wu Xiancheng"
- }
复制代码 以上两段代码不会输出任何内容
Powershell 的比较运算符更是天坑巨雷,一不小心就会坑死炸死。- $Variable = @($Null, $Null, "WU XIANCHENG")
- If($Varible -eq $Null){
- 'IS NULL'
- }Else{
- 'IS NOT NULL'
- }
复制代码 以上代码中,你以为你在检测 $Variable 不是 $Null,预期的结果是 $Variable 不是 $Null,实际上它在检测数组 $variable 中是否包含至少一个值为 $Null 的元素,实际运行时会输出。Powershell 的设计逻辑是,如果比较运算符左边是一个集合,比如数组,Powershell 会将集合中的每一个元素依次取出来做比较,匹配比较条件的元素以一个新的集合的形式返回。
所以,想要正确地对比两个值,尤其是参与对比的值是一个单一元素,最好的操作是,将这个单一元素放在比较运算符的左边,先做类型检测或先比较 Count 属性,再做比较。- $Variable = @($Null, $Null, "WU XIANCHENG")
- If(
- $Variable.Count -eq 0 -and
- $Variable -eq $Null
- ){
- 'IS NULL'
- }Else{
- 'IS NOT NULL'
- }
复制代码- $Variable = "WU XIANCHENG"
- If(
- $Variable -is [String] -and
- $Variable -eq "WU XIANCHENG"
- ){
- 'IS IDENTICAL STRING'
- }Else{
- 'IS NOT IDENTICAL STRING'
- }
复制代码 如果单一元素不是 $Null 而是字符串、数值等其它类型,将 0 改成 1 即可。 |
|