用什么东西来写入Windows的标准输出是正确的?
实际上,但非常不幸的是,Windows PowerShell和PowerShell Core从v7.2开始,当从外部通过PowerShell的CLI调用时,都将它们所有的6(!)输出流发送到stdout。
See GitHub issue #7989 for a discussion of this problematic behavior, which likely won't get fixed, so as to preserve backward compatibility.
In practice, this means that whatever PowerShell stream you send output to will be seen as stdout output by an external caller:
E.g., if you run the following from cmd.exe, you'll see no output, because the stdout redirection to NUL applies equally to all PowerShell streams:
C:\>powershell -noprofile -command "Write-Error error!" >NUL
However - curiously - if you redirect stderr, PowerShell does send its error stream to stderr, so that with 2> you can capture the error-stream output selectively; the following outputs just 'hi' - the success-stream output - while capturing the error-stream output in file err.txt:
C:\>powershell -noprofile -command "'hi'; Write-Error error!" 2>err.txt
理想的行为是:
将PowerShell的成功输出流(编号1)发送到标准输出。
将所有其他流的输出发送到stderr,这是唯一的选项,因为在进程之间只存在两个输出流——用于数据的stdout(标准输出),用于错误消息和所有其他类型的消息(如状态信息)的stderr(标准错误),这些消息都不是数据。
建议在您的代码中进行这种区分,即使目前还没有这样做。
在PowerShell:
Write-Host is for display output, and bypasses the success output stream - as such, its output can neither be (directly) captured in a variable nor suppressed nor redirected.
Its original intent was simply to create user feedback and create simple, console-based user interfaces (colored output).
Due to the prior inability to be captured or redirected, PowerShell version 5 made Write-Host write to the newly introduced information stream (number 6), so since then it is possible to capture and redirect Write-Host output.
Write-Error is meant for writing non-terminating errors to the error stream (number 2); conceptually, the error stream is the equivalent of stderr.
Write-Output writes to the success [output] stream (number 1), which is conceptually equivalent to stdout; it is the stream to write data (results) to.
However, explicit use of Write-Output is rarely needed due to PowerShell's implicit output feature:
Output from any command or expression that isn't explicitly captured, suppressed or redirected is automatically sent to the success stream; e.g., Write-Output "Honey, I'm $HOME" and "Honey, I'm $HOME" are equivalent, with the latter not only being more concise, but also faster.
See this answer for more information.