PowerShell Tee-Object 不捕获文件中的调试行
PowerShell Tee-Object not capturing debug lines in file
我有一个 运行 自动化的 PowerShell 脚本,所以我需要将脚本的输出捕获到一个文件中,但我也想捕获 运行 的命令],为输出提供一些上下文(我会在 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 的 tracing 输出 (通过 Set-PSDebug
) operates outside 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 ({ ... }
) 传递要执行的命令通常更可取,但在这种情况下 不会 起作用,因为脚本块-based 调用在后台使用 PowerShell 的远程处理基础设施,它保留了 PowerShell 特定的输出流(以及类型保真度,但有限制),以便跟踪输出再次直接进入控制台。
[3] 也许令人惊讶的是,all PowerShell 的输出流 - 以及仅控制台输出,例如通过跟踪生成的输出 - 默认情况下映射到外部调用者的 stdout 流 - 包括错误。虽然您至少可以通过 stderr 重定向 on demand 分离出错误 - 2>
- 在调用方,所有剩余的流都是总是发送到标准输出 - 请参阅 this answer and GitHub issue #7989 的底部部分以获取更多信息。
我有一个 运行 自动化的 PowerShell 脚本,所以我需要将脚本的输出捕获到一个文件中,但我也想捕获 运行 的命令],为输出提供一些上下文(我会在 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 的 tracing 输出 (通过 Set-PSDebug
) operates outside 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 ({ ... }
) 传递要执行的命令通常更可取,但在这种情况下 不会 起作用,因为脚本块-based 调用在后台使用 PowerShell 的远程处理基础设施,它保留了 PowerShell 特定的输出流(以及类型保真度,但有限制),以便跟踪输出再次直接进入控制台。
[3] 也许令人惊讶的是,all PowerShell 的输出流 - 以及仅控制台输出,例如通过跟踪生成的输出 - 默认情况下映射到外部调用者的 stdout 流 - 包括错误。虽然您至少可以通过 stderr 重定向 on demand 分离出错误 - 2>
- 在调用方,所有剩余的流都是总是发送到标准输出 - 请参阅 this answer and GitHub issue #7989 的底部部分以获取更多信息。