【问题标题】:Redirection to $null strange behavior in Powershell在 Powershell 中重定向到 $null 奇怪的行为
【发布时间】:2017-02-23 04:34:40
【问题描述】:

有四种方法可以抑制输出:

  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's答案)

  • 在 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. ... | Out-Null 管道到 Out-Null cmdlet
    性能问题 *
  3. [void]... 转换为 [void] 类型
    建议
  4. $null = ... 赋值给 $null 变量
    建议

【问题讨论】:

  • 关于你的编辑:如果你不在表达式中使用return,这看起来很奇怪,你可以安全地使用>$null,因为它比强制转换或分配更合适。
  • @wOxxOm 我可以问你一个例子,> $null 比强制转换或分配更合适吗?
  • 我的意思是主观上/语义上更合适。

标签: powershell null powershell-2.0 void


【解决方案1】:
  • 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 退出当前上下文,然后才能进行后续操作(强制转换、分配、流水线)。

 

至于性能差异,请参阅this answer| Out-Null 是最慢的,因为它创建管道是一个复杂的过程;其他方法丢弃输出,不创建额外内容。

【讨论】:

  • +1 但您可能想更清楚地说明为什么 3 永远不会执行。关于为什么 PS 3.0 只能正确打印 1,我涉猎了很长时间。这只是表明我缺乏知识,但我不能是唯一的 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2017-01-30
  • 2010-12-08
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多