为什么当我们执行 $NULL="FOO" 时 Powershell 不会抛出错误?

Why does Powershell not throw an error when we do $NULL="FOO"?

我试图了解常量 $TRUE$FALSE$NULL 在 Powershell 中的工作原理,以及我应该如何测试它们或分别将它们与变量进行比较。

作为Powershell的新手,我做了一些基本的测试。虽然 $TRUE$FALSE 的行为符合预期,但当我尝试将另一个值分配给 $NULL:

时,我对所看到的内容感到困惑
PS C:\Users\Administrator> $NULL=1

PS C:\Users\Administrator> $NULL="FOO"

PS C:\Users\Administrator> $NULL

PS C:\Users\Administrator> 

$NULL 应该是常量或只读的,不是吗?那么,为什么我可以在没有 Powershell 抛出异常的情况下为其分配另一个值,为什么该分配 静默 被忽略?

相比之下,$FALSE 的行为符合预期:

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的主要原因——尽管作为空值的表示它应该是 constant(例如 other PowerShell automatic variables,例如 $true$false)-是它 输出抑制启用了以下有用的习语 :

# Discard the success output from a command.
$null = Get-Item -ErrorAction Stop foo.txt

也就是说,$null 可以像您可以分配给的常规 read-write 变量一样工作,但是无论您分配给它什么(命令的 成功 来自流编号 1 的输出 - 参见 about_Redirection) 被悄悄丢弃。

实际上,$null = ... 相当于 cmd.exe 中的 >NUL (1>NUL) 和 >/dev/null (1>/dev/null) 在 POSIX-compatible 炮弹中 例如 bash.

请注意,在 PowerShell 中,您可以选择使用 ... | Out-Null> $null,尽管 $null = ... 惯用法比 Out-Null[1] and also signals the intent to discard the (success) output up front (unlike > $null). (There's also [void] (...), but it requires you to enclose the command in parentheses.) See 更多。

但是,如果您还想抑制 other 输出流(也),则确实需要重定向;例如,
*> $null 丢弃来自 all 流的输出。


至于检查变量的属性,包括自动变量的属性,使用Get-Variable cmdlet 并向其传递变量的名称而不是$印记;例如,null 检查 $null.

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  : {}

Format-List * 确保变量对象(System.Management.Automation.PSVariable 实例或派生 class 的实例)的 所有 属性是以列表形式列出。

常量 变量如 $false 将显示 Constant 作为 Options 属性 值的一部分。


[1] 注意:PowerShell [Core] v6+ 进行了优化,如果您丢弃 表达式 ,则 Out-Null 是最快的解决方案值(例如,1..1e6 | Out-Nullcommand 的(例如,Write-Output (1..1e6) | Out-Null),但请注意抑制 command输出是更常见的用例。