告诉PowerShell ISE不要将stderr发送到Write-Error

时间:2012-09-21 19:47:58

标签: powershell powershell-ise

当可执行文件写入标准错误流(stderr)时,PowerShell控制台和PowerShell ISE的行为会有所不同。控制台(powershell.exe)将其显示为标准输出。例如,当我在非存储库上获得Mercurial的状态时,它会写入标准错误:

> hg st -R C:\Windows
abort: repository C:\Windows not found!

但是,在PowerShell ISE(powershell_ise.exe)中,该错误会传递给PowerShell的Write-Error cmdlet:

> hg st -R C:\Windows
hg.exe : abort: repository C:\Windows not found!
At line:1 char:3
+ hg <<<<  st -R C:\Windows
    + CategoryInfo          : NotSpecified: (abort: repository C:\Windows not found!:String) [], RemoteExcepti 
   on
    + FullyQualifiedErrorId : NativeCommandError

有没有办法将ISE配置为像控制台一样,而不是将stderr流发送到Write-Error

2 个答案:

答案 0 :(得分:7)

将stderr输出重定向到stdout“应该”工作,但它不在ISE中。在这种情况下,最好的办法是将错误输出静音,如下所示:

& {
    $ErrorActionPreference = 'SilentlyContinue'
    hg st -R C:\Windows 2>&1
}

通过在嵌套作用域中执行此变量的设置,可以避免全局设置。退出上述范围后,$ErrorActionPreference全局版本仍设置为之前的版本。

不幸的是,ISE和控制台的行为有所不同,但我的理解是,使用“控制台”,另一个控制台应用程序只获取控制台句柄,因此直接输出到控制台(绕过电源外壳)。 ISE不是基于控制台的,所以它试图使本机stderr与PowerShell错误流很好地协同工作。在这种情况下,IMO控制台的行为并不理想。因此,最好让ISE与控制台保持一致或更好地使ISE处理stderr更好(除了关于不遵守流重定向的那一点)?显然,PowerShell采用了后者。

答案 1 :(得分:3)

hg st -R C:\Windows 2>&1 | %{ if ($_ -is [System.Management.Automation.ErrorRecord]) { $_.Exception.Message } else { $_ } }

这会保留stderr输出并将其作为正常输出发送,而不是将其丢弃。