You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Explicit use of Out-Host causes stderr output from external programs not to be recorded in transcripts #11134
Update: This issue was originally about Out-Default, but since the latter is not meant to be called from user code, that is a moot point; however, Out-Host is equally affected, and Out-Host has legitimate end-user uses, namely to send command output to the host rather than to the success stream.
Use of Out-Host should not affect transcription behavior, but it currently does with respect to stderr output from external programs (PowerShell commands aren't affected): such output is unexpectedly not recorded.
Steps to reproduce
Run the following on Windows:
$file= [IO.Path]::GetTempFileName()
Start-Transcript$file# Execute an external command that produces both stdout and stderr output# Note: Without the Out-Host, transcribing works as expected.
cmd /c 'echo stdout & nosuch'|Out-HostStop-TranscriptSelect-String'stdout'$file| Should -match'stdout'Select-String'nosuch'$file| Should -match'nosuch''Tests completed.'Remove-Item$file
Expected behavior
Both tests should pass.
Actual behavior
The 2nd test fails, because stderr output was not recorded.
Expected regular expression 'nosuch' to match $null, but it did not match.
changed the title [-]Out-Default neglects to log stderr output in transcripts[/-][+]Explicit use of Out-Default causes stderr output from external programs not to be recorded in transcripts[/+]on Nov 20, 2019
Out-Host and Out-Default are radically different cmdlets. Out-Default is only intended to be used by the host and requires the pipeline to be set up in a specific way to work properly. I have a more detailed description of what's going on in issue #11135
changed the title [-]Explicit use of Out-Default causes stderr output from external programs not to be recorded in transcripts[/-][+]Explicit use of Out-Default and Out-Host causes stderr output from external programs not to be recorded in transcripts[/+]on Nov 21, 2019
Given that Out-Default is generally not meant to be used directly, the Out-Host case is a more problematic one:
For instance, you could be using | Out-Host for display-only output.
(You could also be using it to force synchronous output from implicitly table-formatted cmdlet output, to ensure correct sequencing of intermixed host and success-stream output in the transcript, but the true PowerShell error stream is properly transcribed - leaving aside that it currently results in duplicate transcript entries; transcribing currently has a number of bugs).
Michael Klement (@mklement0) Setting aside Out-Default, what if you put a Start-Sleep before Stop-Transcription? Or redirect the streams?
Are you trying to use Out-Host to circumvent format timing issues? Because remember, the pipeline is typically just the output stream. The other streams still go through formatting and probably hit similar timing issues.
The only timing issue I am aware of is the 300 msec. delay when table-formatting is implicitly applied to output types that don't have predefined formatting data (as explained here). Are there others?
Yes, Out-Host solves that timing issue, but that use case isn't problematic, because, as stated in the previous comment, true error stream content IS recorded in that case - it is only stderr output from external programs that is missing.
I have no personal use case, but it's conceivable that someone just wants to send command output selectively to the host in a script, using Out-Host, and that should work with external programs too.
Just to be safe, I tried adding Start-Sleep 5 before Stop-Transcript, and it made no difference.
Yes, a 2>&1 redirection would solve the problem - but that shouldn't be necessary.
Ah. Yeah you're right. I think the problem is in the native command processor. There's a ton of edge cases around what's downstream in the pipeline, etc that determines how stdout/err are directed. For anyone looking into it I'd recommend starting around here:
changed the title [-]Explicit use of Out-Default and Out-Host causes stderr output from external programs not to be recorded in transcripts[/-][+]Explicit use of Out-Host causes stderr output from external programs not to be recorded in transcripts[/+]on Nov 24, 2019
If someone is looking for a real use-case that demonstrates this issue, I have one. I'm currently trying to capture output produced by ffmpeg in a PowerShell script so I can parse it, but there doesn't seem to be any good way to achieve this. I'm not sure why, but ffmpeg writes its output to stderr.
Redirecting stderr to stdout is problematic because it prevents interactive prompts from being printed (e.g., asking the user if they wish to overwrite an existing file). Additionally, it makes all the output red, clobbering the highlighting used by ffmpeg to make the output easier to read.
Using Start-Transcript was my next approach, but this only prints a small subset of the output generated by ffmpeg, likely due to Issue #10994. The comments on that issue suggest using Out-Default or Out-Host as a workaround, but these workarounds fail for this case, likely due to this issue.
Activity
[-]Out-Default neglects to log stderr output in transcripts[/-][+]Explicit use of Out-Default causes stderr output from external programs not to be recorded in transcripts[/+]vexx32 commentedon Nov 20, 2019
/cc Paul Higinbotham (@PaulHigin)
This seems kind of strange to me. Does the same thing happen with
Out-Hostas well?BrucePay commentedon Nov 21, 2019
Rain Sallow (/u/ta11ow) (@vexx32)
Out-HostandOut-Defaultare radically different cmdlets.Out-Defaultis only intended to be used by the host and requires the pipeline to be set up in a specific way to work properly. I have a more detailed description of what's going on in issue #11135[-]Explicit use of Out-Default causes stderr output from external programs not to be recorded in transcripts[/-][+]Explicit use of Out-Default and Out-Host causes stderr output from external programs not to be recorded in transcripts[/+]mklement0 commentedon Nov 21, 2019
Good question, Rain Sallow (/u/ta11ow) (@vexx32): Yes, the same thing happens with
Out-Host(I've updated the title and the OP).Given that
Out-Defaultis generally not meant to be used directly, theOut-Hostcase is a more problematic one:For instance, you could be using
| Out-Hostfor display-only output.(You could also be using it to force synchronous output from implicitly table-formatted cmdlet output, to ensure correct sequencing of intermixed host and success-stream output in the transcript, but the true PowerShell error stream is properly transcribed - leaving aside that it currently results in duplicate transcript entries; transcribing currently has a number of bugs).
SeeminglyScience commentedon Nov 21, 2019
Michael Klement (@mklement0) Setting aside
Out-Default, what if you put aStart-SleepbeforeStop-Transcription? Or redirect the streams?Are you trying to use
Out-Hostto circumvent format timing issues? Because remember, the pipeline is typically just the output stream. The other streams still go through formatting and probably hit similar timing issues.mklement0 commentedon Nov 21, 2019
The only timing issue I am aware of is the 300 msec. delay when table-formatting is implicitly applied to output types that don't have predefined formatting data (as explained here). Are there others?
Yes,
Out-Hostsolves that timing issue, but that use case isn't problematic, because, as stated in the previous comment, true error stream content IS recorded in that case - it is only stderr output from external programs that is missing.I have no personal use case, but it's conceivable that someone just wants to send command output selectively to the host in a script, using
Out-Host, and that should work with external programs too.Just to be safe, I tried adding
Start-Sleep 5beforeStop-Transcript, and it made no difference.Yes, a
2>&1redirection would solve the problem - but that shouldn't be necessary.SeeminglyScience commentedon Nov 21, 2019
Ah. Yeah you're right. I think the problem is in the native command processor. There's a ton of edge cases around what's downstream in the pipeline, etc that determines how stdout/err are directed. For anyone looking into it I'd recommend starting around here:
PowerShell/src/System.Management.Automation/engine/NativeCommandProcessor.cs
Lines 1191 to 1212 in 8d944fd
[-]Explicit use of Out-Default and Out-Host causes stderr output from external programs not to be recorded in transcripts[/-][+]Explicit use of Out-Host causes stderr output from external programs not to be recorded in transcripts[/+]Makumasa commentedon Jun 5, 2024
Please re-open this issue.
If someone is looking for a real use-case that demonstrates this issue, I have one. I'm currently trying to capture output produced by
ffmpegin a PowerShell script so I can parse it, but there doesn't seem to be any good way to achieve this. I'm not sure why, butffmpegwrites its output to stderr.Redirecting stderr to stdout is problematic because it prevents interactive prompts from being printed (e.g., asking the user if they wish to overwrite an existing file). Additionally, it makes all the output red, clobbering the highlighting used by
ffmpegto make the output easier to read.Using
Start-Transcriptwas my next approach, but this only prints a small subset of the output generated byffmpeg, likely due to Issue #10994. The comments on that issue suggest usingOut-DefaultorOut-Hostas a workaround, but these workarounds fail for this case, likely due to this issue.