【问题标题】:PowerShell Tee-Object not capturing debug lines in filePowerShell Tee-Object 未捕获文件中的调试行
【发布时间】:2021-01-30 10:51:35
【问题描述】:

我有一个通过自动化运行的 PowerShell 脚本,因此我需要将脚本的输出捕获到一个文件中,但我还想捕获运行的命令,以便为输出提供一些上下文(I' d 在 Linux shell 脚本中使用set -x)。不过,我不知道如何将这些命令捕获到 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 trace io-redirection


    【解决方案1】:

    不幸的是,PowerShell 的跟踪输出(通过Set-PSDebug激活)在外部PowerShell's system of output streams运行,所以这样的输出不能从 PowerShell 会话内部捕获。[1]

    但是,PowerShell's CLI[2]外部 调用者,例如您的情况中的 cmd.exe确实通过 stdout(标准输出流)[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 名称中包含“Debug”一词,跟踪输出通过流号5,调试流, Write-Debug 输出的方式。

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

    [3] 或许令人惊讶的是,PowerShell 的所有输出流以及仅控制台的输出(例如由跟踪产生的输出)在默认情况下都映射到外部调用者的 >stdout 流 - 包括错误。虽然您至少可以通过 stderr 重定向 - 2> - 在调用方端分离出错误on demand,但所有剩余的流总是发送到标准输出 - 见底部this answerGitHub issue #7989 部分了解更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2019-04-09
      • 2019-08-20
      • 2019-04-17
      • 1970-01-01
      相关资源
      最近更新 更多