PowerShellTee-Object未捕获文件中的调试行

我有一个通过自动化运行的 PowerShell 脚本,所以我需要将脚本的输出捕获到一个文件中,但我还想捕获运行的命令,为输出提供一些上下文(我会set -x在Linux shell 脚本)。我不知道如何将这些命令捕获到 Windows 中的输出文件中;任何帮助深表感谢!

# script.ps1

Set-PSDebug -Trace 1
Write-Host "Hello, World!"

我如何调用脚本(从 cmd):

$ powershell -command "./script.ps1 *>&1 | Tee-Object -FilePath ./output.txt"

终端输出:

DEBUG:    2+  >>>> Write-Host "Hello, World!"
Hello, World!

output.txt 文件内容:

Hello, World!

您可以看到输出文件缺少终端中显示的调试行。理想情况下,我希望调试行只在输出文件中(不是终端输出),但在两个地方都有调试行也可以。

请注意,PowerShell 5.1 是我安装的版本。

回答

不幸的是,PowerShell 的跟踪输出(通过 激活Set-PSDebug PowerShell 的输出流系统之外运行,因此无法从PowerShell 会话内部捕获此类输出[1]

但是,PowerShell 的 CLI [2]外部调用者(例如在您的情况下)确实通过 stdoutcmd.exe(标准输出流)[3]接收跟踪输出,因此您可以使用cmd.exe的重定向来捕获文件中的所有内容并打印它之后到控制台。

一个简化的例子(来自cmd.exe):

C:>powershell -c "Set-PSDebug -Trace 1; Write-Host 'Hello, World!'" > output.txt & type output.txt

DEBUG:    1+ Set-PSDebug -Trace 1;  >>>> Write-Host 'Hello, World!'
Hello, World!

[1] 也许令人惊讶的是,尽管 cmdlet 名称中有“调试”一词,但跟踪输出并没有像输出那样经过流编号5、调试流Write-Debug

[2] 请注意,您也可以使用这种从现有 PowerShell 会话内部调用 CLI 的技术,始终作为子进程,在这种情况下,现有会话充当外部调用者。但是,注意,通过命令通过执行脚本块{ ... }),这通常是最好,会不会在这种情况下工作,因为基于块的脚本调用使用PowerShell的幕后远程处理基础结构,它保留了PowerShell的特定输出流(还有类型保真度,有限制),以便跟踪输出再次直接进入控制台。

[3] 也许令人惊讶的是,所有PowerShell 的输出流 - 以及仅到控制台的输出,例如由跟踪产生的 - 默认情况下都映射到外部调用者的stdout流 - 包括错误。虽然您至少可以通过stderr重定向按需分离错误- 在调用方,所有剩余的流总是发送到 stdout -有关更多信息,请参阅此答案的底部和GitHub 问题 #7989。2>


以上是PowerShellTee-Object未捕获文件中的调试行的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>