简体   繁体   English

PowerShell 脚本未捕获 git output

[英]PowerShell Transcript is not capturing git output

I'm writing a script that will perform some git actions and I want to use Start-Transcript to monitor it.我正在编写一个脚本来执行一些 git 操作,我想使用Start-Transcript来监控它。 The transcript is however missing most of the git output.然而,成绩单缺少大部分git output。

I've tried to pipe the git output to both Out-Host and Out-Default but neither work.我已经尝试将 pipe 和git output 同时设置为Out-HostOut-Default但都不起作用。

Here's my code...这是我的代码...

$DateTime = Get-Date -Format "yyyyMMdd_HHmmss"
$TranscriptName = "PSTranscript_$DateTime"

Start-Transcript -Path ".\$TranscriptName.txt"

git --bare clone <GIT_REPO_URL> repo | Out-Default

Stop-Transcript

Here's my console output...这是我的控制台 output...

Transcript started, output file is .\PSTranscript_20191119_155424.txt
Cloning into 'repo'...
remote: Counting objects: 58975, done.
remote: Compressing objects: 100% (21457/21457), done.
remote: Total 58975 (delta 43348), reused 51727 (delta 37145)
Receiving objects: 100% (58975/58975), 70.46 MiB | 3.95 MiB/s, done.
Resolving deltas: 100% (43348/43348), done.
Checking out files: 100% (3878/3878), done.
Transcript stopped, output file is .\PSTranscript_20191119_155424.txt

And here's what is captured in the transcript, note that some of the git output is missing这是记录中捕获的内容,请注意,缺少一些git output

**********************
Windows PowerShell transcript start
Start time: 20191119155424
Username: 
RunAs User: 
Configuration Name: 
Machine: 
Host Application: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Process ID: 20644
PSVersion: 5.1.17134.858
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.17134.858
BuildVersion: 10.0.17134.858
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
Transcript started, output file is .\PSTranscript_20191119_155424.txt
**********************
Windows PowerShell transcript end
End time: 20191119155457
**********************

Edit : I make a mistake in leaving the Out-Default in my original code.编辑:我在原始代码中保留Out-Default时犯了一个错误。 This hits a bug in Out-Default that specifically affects stderr .这在Out-Default中遇到了一个专门影响stderr的错误。 Removing the Out-Default resulted in fixing my script and it now successfully transcribes git output.删除Out-Default导致修复了我的脚本,它现在成功转录 git output。


@VonC posted a very helpful link that pointed me in the right direction! @VonC 发布了一个非常有用的链接,为我指明了正确的方向!

All that needed done was adding the GIT_REDIRECT_STDERR environment variable with the value 2>&1 to Windows User environment variables.所需要做的就是将值为2>&1GIT_REDIRECT_STDERR环境变量添加到 Windows 用户环境变量。

If you're on Windows, here's a nifty PowerShell command you can run to add the environment variable.如果您使用的是 Windows,这里有一个漂亮的 PowerShell 命令,您可以运行它来添加环境变量。

[System.Environment]::SetEnvironmentVariable("GIT_REDIRECT_STDERR", "2>&1", "User")

Below is what my new transcript looks like...下面是我的新成绩单的样子……

**********************
Windows PowerShell transcript start
Start time: 20191119165056
Username: 
RunAs User: 
Configuration Name: 
Machine: 
Host Application: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Process ID: 16440
PSVersion: 5.1.17134.858
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.17134.858
BuildVersion: 10.0.17134.858
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
Transcript started, output file is .\PSTranscript_20191119_165056.txt
Cloning into bare repository 'repo'...
remote: Counting objects: 58975, done.
remote: Compressing objects: 100% (21457/21457), done.
remote: Total 58975 (delta 43347), reused 51727 (delta 37145)
Receiving objects: 100% (58975/58975), 70.33 MiB | 6.04 MiB/s, done.
Resolving deltas: 100% (43347/43347), done.
**********************
Windows PowerShell transcript end
End time: 20191119165115
**********************

There's no reason to call Out-Default - just use your git command as-is , and your problem will go away: both its stdout and stderr streams will be transcribed.没有理由调用Out-Default - 只需按原样使用您的git命令,您的问题将 go 消失:它的 stdout 和 stderr 流都将被转录。

git writes status information to stderr by default, and the - mistaken - use of Out-Default affects stderr output specifically, as described in the bottom section. git默认情况下将状态信息写入stderr ,并且 - 错误 - 使用Out-Default会影响 stderr output 具体,如底部所述。

The following example demonstrates that both stdout and stderr output are captured in the transcript:以下示例演示了在脚本中捕获了 stdout 和 stderr output :

$file = [IO.Path]::GetTempFileName()

"--- DIRECT OUTPUT ---`n"

Start-Transcript $file

# Execute a command that produces
# both stdout and stderr output.
# Do NOT use Out-Default.
if ($env:OS -eq 'Windows_NT') {  # Windows
  cmd /c 'echo hi & nosuch'
} else {                         # macOS, Linux
  sh -c 'echo hi; nosuch'
}

Stop-Transcript

"`n--- CORE CONTENT OF TRANSCRIPT ---"

# Print the core of the transcript.
((Get-Content -Raw $file) -split '(?m)^\*+\s*$')[2]

Remove-Item $file

On Windows, you'll see something like the following, demonstrating that both streams were captured:在 Windows 上,您将看到类似以下内容,表明两个流均已被捕获:

--- DIRECT OUTPUT ---

Transcript started, output file is C:\Users\jdoe\AppData\Local\Temp\tmp342C.tmp
hi
'nosuch' is not recognized as an internal or external command,
operable program or batch file.
Transcript stopped, output file is C:\Users\jdoe\AppData\Local\Temp\tmp342C.tmp

--- CORE CONTENT OF TRANSCRIPT ---

Transcript started, output file is C:\Users\jdoe\AppData\Local\Temp\tmp342C.tmp
hi
'nosuch' is not recognized as an internal or external command,
operable program or batch file.

The purpose of the Out-Default cmdlet: Out-Default cmdlet 的用途:

Out-Default is not meant to be called from user code. Out-Default并不意味着从用户代码中调用。

Instead, it is meant to be used only by PowerShell host applications , including PowerShell itself.相反,它仅供PowerShell 主机应用程序使用,包括 PowerShell 本身。 It creates pretty-printed string representations of the output objects using PowerShell's output-formatting system and sends them to the host for display.它使用PowerShell 的输出格式系统创建 output 对象的漂亮打印字符串表示,并将它们发送到主机进行显示。

The reason that it is a public cmdlet is that you are allowed to override it in order to define a custom output formatter, although doing so is rare.它是公共 cmdlet 的原因是允许您覆盖它以定义自定义output 格式化程序,尽管这样做很少见。

Overriding is as simple as defining an advanced Out-Default function in your session, which must have the same parameter declarations and pipeline-binding behavior.覆盖就像在 session 中定义高级Out-Default function 一样简单,它必须具有相同的参数声明和管道绑定行为。 You can scaffold such a function via a wrapper (proxy) function , as demonstrated in the bottom section of this answer ).您可以通过包装器(代理) function为这样的 function 搭建支架,如本答案底部所示)。 Note that in order to produce visible output from your function, you must send your custom-formatted strings either to the original Out-Default or use the host APIs to print them ( Write-Host , in the simplest case).请注意,为了从 function 生成可见的 output,您必须将自定义格式的字符串发送到原始Out-Default或使用主机 API打印它们(在最简单的情况下为Write-Host )。


Bug:漏洞:

Your use of Out-Default - though ill-advised - should arguably still have worked.您对Out-Default的使用 - 尽管不明智 - 可以说仍然有效。

While that is a moot point for Out-Default , given that it shouldn't be called directly, Out-Host exhibits the same problem (as of PowerShell Core 7.0.0-preview.6), and there are legitimate reasons to call Out-Host , namely to explicitly print to the display only (and doing so should not affect transcription behavior).虽然这是Out-Default的一个争论点,但鉴于不应直接调用它, Out-Host表现出相同的问题(从 PowerShell Core 7.0.0-preview.6 开始),并且正当理由调用Out-Host ,即仅显式打印到显示器(这样做不应影响转录行为)。

Specifically, if you use Out-Host explicitly, stderr output from external programs is unexpectedly not recorded in the transcript.具体来说,如果您明确使用Out-Host ,则来自外部程序stderr output 意外不会记录在脚本中。 (By contrast, the problem doesn't surface with PowerShell commands.) (相比之下,PowerShell 命令不会出现问题。)

The problem has been reported in this GitHub issue .此问题已在此 GitHub 问题中报告。

Start-Transcript should capture everything written to the console host regardless of which stream it writes to. Start-Transcript应该捕获写入控制台主机的所有内容,无论它写入哪个 stream。 However, I did notice that when I pipe a git command to Out-Default , I get NOTHING written to the transcript for that command, even though it displays to the console.但是,我确实注意到,当我将 pipe 一个 git 命令设置为Out-Default时,即使它显示在控制台上,我也没有写入该命令的脚本。

I can't explain why this happens, but remove | Out-Default我无法解释为什么会发生这种情况,但请删除| Out-Default | Out-Default from your clone command and it should log the output to the transcript.您的克隆命令| Out-Default ,它应该将 output 记录到脚本中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM