有四种抑制输出的方法:
- 重定向到
$null
变量PS C:> 1; $(2; return) > $null; 3 1 3
- 管道到
Out-Null
CMDLETPS C:> 1; $(2; return) | Out-Null; 3 1 2
- 铸造到
[void]
类型PS C:> 1; [void]$(2; return); 3 1 2
- 分配给
$null
变量PS C:> 1; $null = $(2; return); 3 1 2
所有四个案例都应等效。
为什么重定向$null
的行为不同?我遇到了错误吗?
附加示例
此示例显示PS 2.0中> $null
命令的意外行为:
PS C:> 1; $(Write-Output 2; Write-Host 3; return; Write-Host 4) > $null; 5
1
3
5
return
命令像从某些嵌套上下文中退出(尽管没有创建它的命令),停止$()
表达式执行,然后在当前上下文中继续执行(当它不应该)到Write-Output 5
命令。
行为解释
(来自 woxxom 的答案)
- 在PS 1.0和2.0中,
> $null
操作在$()
表达之前执行并抑制其输出;return
命令不从当前上下文(考虑 bug )退出,但停止$()
表达式执行 - 在PS 3.0中,在
$()
表达式之前执行了较新的> $null
操作,并在所有情况下都抑制其输出;return
命令从当前上下文完全退出 -
| Out-Null
,[void]
,$null =
操作在$()
表达后执行,如果其中没有return
命令,则抑制其输出;return
命令从当前上下文完全退出
摘要
抑制命令输出的不同方法:
-
... > $null
重定向$null
变量
PS 1.0和2.0中的错误。在PS 3.0 中,输出可能与其他方法
有所不同。 -
... | Out-Null
管道到Out-Null
CMDLET
性能问题* -
[void]...
铸造到[void]
类型
建议 -
$null = ...
分配给$null
变量
建议
-
2
实际上是Write-Output 2
-
$()
在同一上下文中执行封闭的代码,它不会创建新的上下文。创建新上下文的事物是
& { ... }
,1..2 | ForEach { ... }
,
等脚本块({ ... }).Invoke()
,select @{N='calculated property'; E={$_.foo}}
和功能。 -
因此,
$( return )
从当前上下文中退出,因此在此之后不得评估任何内容(换句话说,PowerShell 1.0和2.0具有错误)。
重定向输出流:
1; $(2; return) > $null; 3
>$null
抑制了整个$()
表达式的输出流本身,在评估表达式之前,return
在3
有机会之前从当前上下文中退出。
ps 3(和较新)正确打印1
:
1
ps 1和2错误地打印两个数字,确实是一个错误:
1
3
处理输出流:
1; [void]$(2; return); 3
1; $null = $(2; return); 3
1; $(2; return) | Out-Null; 3
1
2
2
在此处推到输出流,然后return
在可以进行后续操作之前退出当前上下文(铸造,分配,管道)。
至于性能差异,请参见以下答案:| Out-Null
是最慢的,因为它创建了一个复杂过程的管道;其他方法丢弃了输出,未创建其他。