为什么Powershell在执行$NULL=“FOO”时不抛出错误?
我试图理解常量$TRUE、$FALSE和$NULL在Powershell中是如何工作的,以及我应该如何分别测试它们或将它们与变量进行比较 作为一名Powershell新手,我做了一些基本测试。虽然$TRUE和$FALSE的行为与预期一致,但当我尝试将另一个值赋给$NULL时,我对所看到的情况感到困惑: $NULL应该是常量或只读的,不是吗?那么,为什么我可以在没有Powershell引发异常的情况下为其分配另一个值,为什么该分配会被默默地忽略呢 相反,$FALSE的行为与预期的一样:为什么Powershell在执行$NULL=“FOO”时不抛出错误?,powershell,null,constants,readonly-variable,Powershell,Null,Constants,Readonly Variable,我试图理解常量$TRUE、$FALSE和$NULL在Powershell中是如何工作的,以及我应该如何分别测试它们或将它们与变量进行比较 作为一名Powershell新手,我做了一些基本测试。虽然$TRUE和$FALSE的行为与预期一致,但当我尝试将另一个值赋给$NULL时,我对所看到的情况感到困惑: $NULL应该是常量或只读的,不是吗?那么,为什么我可以在没有Powershell引发异常的情况下为其分配另一个值,为什么该分配会被默默地忽略呢 相反,$FALSE的行为与预期的一样: PS C:
PS C:\Users\Administrator> $FALSE=1
Cannot overwrite variable false because it is read-only or constant.
At line:1 char:1
+ $FALSE=1
+ ~~~~~~~~
+ CategoryInfo : WriteError: (false:String) [], SessionStateUnauthorizedAccessException
+ FullyQualifiedErrorId : VariableNotWritable
PS C:\Users\Administrator>
您可以将$null赋值的主要原因是,它支持以下有用的输出抑制习惯用法,即使作为null值的表示形式,它应该是常量,例如,与其他PowerShell(如$true和$false)一样:
也就是说,$null可以像一个常规的读写变量一样工作,您可以分配给它,但是无论您分配给它什么,来自流1-see的命令的成功输出都会被悄悄地丢弃
实际上,$null=。。。相当于cmd.exe中的>NUL 1>NUL和POSIX兼容shell(如bash)中的>/dev/null 1>/dev/null
请注意,在PowerShell中,您也可以使用…|Out Null或>$Null,尽管$Null=。。。成语比[1]快,并且表示要提前放弃成功输出,而不是>$null。还有[void]…,但它需要将命令括在括号中。更多信息,请参阅
但是,如果您还想抑制其他输出流,则确实需要重定向;例如。,
*>$null丢弃所有流的输出
至于检查变量(包括自动变量)的属性,请使用cmdlet并将变量名传递给它,而不使用$sigil;e、 例如,null检查$null
Format List*确保以列表形式列出变量对象实例或派生类实例的所有属性
常量变量(如$false)将显示常量作为选项属性值的一部分
[1] 注意:PowerShell[Core]v6+有一个优化,如果您放弃表达式的值(例如1..1e6 | Out Null)而不是命令的值(例如写入输出1..1e6 | Out Null),则Null是最快的解决方案,但是请注意,抑制命令输出是更常见的用例。您可以将$null指定给的主要原因是,即使作为null值的表示形式,它应该是常量,例如,与其他PowerShell(如$true和$false)一样,它启用了以下有用的输出抑制习惯用法:
也就是说,$null可以像一个常规的读写变量一样工作,您可以分配给它,但是无论您分配给它什么,来自流1-see的命令的成功输出都会被悄悄地丢弃
实际上,$null=。。。相当于cmd.exe中的>NUL 1>NUL和POSIX兼容shell(如bash)中的>/dev/null 1>/dev/null
请注意,在PowerShell中,您也可以使用…|Out Null或>$Null,尽管$Null=。。。成语比[1]快,并且表示要提前放弃成功输出,而不是>$null。还有[void]…,但它需要将命令括在括号中。更多信息,请参阅
但是,如果您还想抑制其他输出流,则确实需要重定向;例如。,
*>$null丢弃所有流的输出
至于检查变量(包括自动变量)的属性,请使用cmdlet并将变量名传递给它,而不使用$sigil;e、 例如,null检查$null
Format List*确保以列表形式列出变量对象实例或派生类实例的所有属性
常量变量(如$false)将显示常量作为选项属性值的一部分
[1] 注意:PowerShell[Core]v6+有一个优化,如果您放弃表达式的值(例如1..1e6 | Out Null)而不是命令的值(例如写入输出1..1e6 | Out Null),则Null是最快的解决方案,但是请注意,抑制命令输出是更常见的用例。因为$null不是一个常量-它是一个特殊的变量,具有多重责任-它解析为null,它充当[void]-sink用于像在您的帖子中这样的分配,它的功能是替换cmd中的NUL设备:$anyValue>$nullRun Get Variable False | fl和Get Variable null | fl。您将看到它们的构建方式不同。另外:$null=foo相当于foo | Out null或[Void]foo。据称,第一种模式是3种模式中速度最快的。在PowerShell 7中,Out Null得到了改进,据称是最快的。根据我在7之前的经验,它比Out Null快很多,但比强制转换到[Void]快不了多少。例如,如果您只是在学习PowerShell,请注意与$Null的比较是如何工作的$
null-eq@返回$false,但@eq$null返回$null,因为如果左侧值可枚举,它将返回与右侧匹配的任何项目-例如@aaa,bbb-eq bbb返回bbb。经验法则是当与$null进行比较时,将$null放在左边。@Steven,这是好的观点,但请注意,PS[Core]v6+中的Out null仅在放弃表达式的输出时才得到优化,然而这是一个非典型的用例。对于丢弃命令输出的典型用例,它仍然是最慢的选项-请参阅我在答案中添加的脚注。因为$null不是常量-它是一个特殊的变量,承担多个责任-它解析为null,充当[void]-sink用于像在您的帖子中这样的分配,它的功能是替换cmd中的NUL设备:$anyValue>$nullRun Get Variable False | fl和Get Variable null | fl。您将看到它们的构建方式不同。另外:$null=foo相当于foo | Out null或[Void]foo。据称,第一种模式是3种模式中速度最快的。在PowerShell 7中,Out Null得到了改进,据称是最快的。根据我在7之前的经验,它比Out Null快很多,但比强制转换到[Void]快不了多少。如果您只是在学习PowerShell,请注意与$Null的比较是如何工作的,例如,$null-eq@返回$false,@-eq$null返回$null,因为如果左侧值是可枚举的,它将返回与右侧匹配的任何项-例如@aaa,bbb-eq bbb返回bbb。经验法则是当与$null进行比较时,将$null放在左边。@Steven,这是好的观点,但请注意,PS[Core]v6+中的Out null仅在放弃表达式的输出时才得到优化,然而这是一个非典型的用例。对于丢弃命令输出的典型用例,它仍然是最慢的选项——请参阅我在答案中添加的脚注。
PS C:\Users\Administrator> $FALSE=1
Cannot overwrite variable false because it is read-only or constant.
At line:1 char:1
+ $FALSE=1
+ ~~~~~~~~
+ CategoryInfo : WriteError: (false:String) [], SessionStateUnauthorizedAccessException
+ FullyQualifiedErrorId : VariableNotWritable
PS C:\Users\Administrator>
# Discard the success output from a command.
$null = Get-Item -ErrorAction Stop foo.txt
PS> Get-Variable null | Format-List
Value :
Description : References to the null variable always return the null value. Assignments have no effect.
Options : None
Name : null
Visibility : Public
Module :
ModuleName :
Attributes : {}