在PowerShell中重定向$ null奇怪的行为



有四种抑制输出的方法:

  1. 重定向到$null变量
    PS C:> 1; $(2; return) > $null; 3
    1
    3
    
  2. 管道到Out-Null CMDLET
    PS C:> 1; $(2; return) | Out-Null; 3
    1
    2
    
  3. 铸造到[void]类型
    PS C:> 1; [void]$(2; return); 3
    1
    2
    
  4. 分配给$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命令从当前上下文完全退出

摘要

抑制命令输出的不同方法:

  1. ... > $null重定向 $null变量
    PS 1.0和2.0中的错误。在PS 3.0 中,输出可能与其他方法
  2. 有所不同。
  3. ... | Out-Null管道到Out-Null CMDLET
    性能问题*
  4. [void]...铸造到[void]类型
    建议
  5. $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抑制了整个$()表达式的输出流本身,在评估表达式之前,return3有机会之前从当前上下文中退出。

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是最慢的,因为它创建了一个复杂过程的管道;其他方法丢弃了输出,未创建其他。

相关内容

  • 没有找到相关文章

最新更新