【问题标题】:powershell - capture stdout and stderr to files while also keeping them in the terminalpowershell - 将标准输出和标准错误捕获到文件中,同时将它们保存在终端中
【发布时间】:2020-04-03 17:28:29
【问题描述】:

我有一个脚本,它通过 Write-Output 和 Write-Error 记录,并调用许多其他脚本和可执行文件。 当我直接运行它时,我对在终端中看到的内容感到满意。 但我想另外将两个流捕获到两个单独的文件中,同时保持终端中的行为。

这很接近,但终端没有得到标准错误:

& .\main.ps1 2> stderr.log | Tee-Object -FilePath stdout.log

我曾考虑将它作为后台任务运行,但我担心我会轻易失去按 Ctrl-C 的能力。我的工作会被很多工程师使用,所以我不想引入意外的行为。

【问题讨论】:

  • 由于您已经要求执行程序知道错误和文件名,您可以将该功能移至脚本内部。您可以在main.ps1 中为stderr.log 文件名添加一个参数(称为errorfile)。在有write-error "some error"的区域,你可以添加$error[0] > $errorfile。然后你的可运行命令变成& .\main.ps1 stderr.log | Tee-Object -FilePath stdout.log
  • 嗨,谢谢。这是有道理的,但不幸的是,我需要或多或少地将 main.ps1 视为一个黑匣子。我没有提到 main.ps1 只是一大堆脚本和可执行文件的冰山一角,并不是我能够修改的所有内容。 (编辑问题)

标签: powershell redirect terminal stdout stderr


【解决方案1】:

如果你能接受这样一个事实,即两个流都放在一个文件中(基本上就像终端中的视图一样),这将起到作用:

& .\main.ps1 2>&1 | Tee-Object -FilePath stdout_and_stderr.log

它将stderr 重定向到stdout 并像以前一样将其通过管道传输到Tee-Object

【讨论】:

  • 谢谢。这很可能是我要做的,尽管这不是我打算做的。我正在运行的主脚本也在我不拥有的服务上运行,它在单独的文件中捕获两个流,我想在交互式终端会话上运行时尽可能地模拟这种行为。可能我会将它们都发送到单个stdout.txt 文件中,然后将“stderr 合并到 stdout.txt”之类的内容写入 stderr.txt。再次感谢。
【解决方案2】:
# (Re)create the log files.
New-Item stdout.log, stderr.log -Force

# Merge the error stream (2) into the success stream (1) with 2>&1
# Then use the type of the objects to distinguish between 
# error-stream output (whose objects are of type [System.Management.Automation.ErrorRecord])
# and success-stream output (all other types).
.\main.ps1 2>&1 | ForEach-Object {
  if ($_ -is [System.Management.Automation.ErrorRecord]) { $_ >> stderr.log }
  else                                                   { $_ >> stdout.log }
  $_ # pass through
}

注意:鉴于输出文件在每次迭代中都会打开和关闭(用于附加到通过>>,这个解决方案会很慢。

【讨论】:

    猜你喜欢
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 2012-05-26
    • 2017-06-09
    • 1970-01-01
    • 2010-09-11
    • 2018-11-25
    相关资源
    最近更新 更多