当可执行文件写入标准错误流(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
?
答案 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输出并将其作为正常输出发送,而不是将其丢弃。