Skip to content

Suggestion: Add redirection syntax that allows in-memory collection of stderr lines output by external utilities, akin to the -ErrorVariable common parameter #4332

@mklement0

Description

@mklement0

This was first proposed as part of a lengthy exchange in #3996, but I thought it deserved its own post.

tl;dr

In order to collected stderr output (separately) from an external-utility call in memory, I suggest supporting the following new redirection syntax that allows capturing stderr lines in a variable, akin to the common -ErrorVariable parameter for cmdlets (the sample cmd command is designed to produce both stdout and stderr output):

# Wishful thinking: Collect stderr lines in given variable $stderrOutput via 2>&
$stdoutOutput = cmd /c ver '&' dir \nosuch 2>&stderrOutput 

Instead of what you must currently do:

$stderrFile = New-TemporaryFile
$stdoutOutput = cmd /c ver '&' dir \nosuch 2>$stderrFile
$stderrOutput = Get-Content $stdErrFile
Remove-Item $stderrFile

The current behavior is to pass stderr output generated by external utility calls (e.g., to git) through to the console - stderr output is not recorded in $Error, which makes sense, given that many utilities write much more than just error information to stderr, and that the presence of stderr input doesn't imply actual errors.

Sometimes it is necessary to inspect stderr output, however, which is currently not easily accomplished:

You can redirect stderr output by redirecting PowerShell's error stream: 2>..., but you're faced with 2 options, neither of which is convenient:

  • Either: redirect stderr output to a file with 2>filename

  • Or: redirect stderr output into the success stream with 2>&1 to produce a combined stream from which you can later filter out the stderr lines by type ([System.Management.Automation.ErrorRecord]).

Therefore, I propose a new redirection syntax that allows capturing stderr lines in a variable, akin to the common -ErrorVariable parameter for cmdlets, so that:

  • foo.exe 2>&errs would be the external-utility-call equivalent of a (fictitious) Invoke-Foo -ErrorVariable errs 2>$null call, with errors getting collected in variable $errs in both cases.

  • Additionally, to allow stderr output to also be passed through while being collected:
    foo.exe 2>&|errs could be the equivalent of Invoke-Foo -ErrorVariable errs

The suggestion is to use >&varName syntax, because & is already established as having into-a-different-target(-stream) semantics, yet currently only a digit is supported after the & (the index of a different PS stream).
(There is still ambiguity, given that $1 is a valid variable name, but I think that wouldn't be a real-world concern.)

Also, given that -ErrorVariable supports a + prefix to the variable name to indicate that the existing variable value should be appended to, this new syntax should support that too.

Environment data

PowerShell Core v6.0.0-beta.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugResolution-No ActivityIssue has had no activity for 6 months or moreWG-Languageparser, language semantics

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions