Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tell PowerShell ISE to not send stderr to Write-Error

The PowerShell console and the PowerShell ISE behave differently when executables write to the standard error stream (stderr). The console (powershell.exe) displays it like standard output. For example, when I get a status with Mercurial on a non-repository, it writes to standard error:

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

However, in the PowerShell ISE (powershell_ise.exe), that error gets passed to PowerShell's 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

Is there any way to configure the ISE to behave like the console, and not send the stderr stream to Write-Error?

like image 395
Aaron Jensen Avatar asked Sep 21 '12 19:09

Aaron Jensen


2 Answers

Redirecting the stderr output to stdout "should" work but it doesn't in ISE. In this case, your best bet is to silence the error output like so:

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

By executing setting this variable in a nested scope, you avoid setting it globally. When the scope above is exited, the global version of $ErrorActionPreference is still set to whatever it was before.

It is unfortunate that ISE and the console behave differently but it is my understanding that with the "console", another console app just gets the console handle so it is outputting directly to the console (bypassing PowerShell). ISE isn't console based so it is trying to make native stderr play nicely with the PowerShell error stream. IMO the behavior of console isn't ideal in this case. So is it better to have ISE be consistent with console or better to have ISE handle stderr better (except the bit about not honoring stream redirection)? Obviously the PowerShell went with the latter.

like image 78
Keith Hill Avatar answered Sep 24 '22 18:09

Keith Hill


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

This preserves the stderr output and sends it as normal output, rather than dropping it.

like image 33
Zenexer Avatar answered Sep 21 '22 18:09

Zenexer