PowerShell脚本未捕获git输出 [英] PowerShell Transcript is not capturing git output

查看:213
本文介绍了PowerShell脚本未捕获git输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个脚本,它将执行一些git操作,并且我想使用Start-Transcript对其进行监视.但是,该笔录缺少大部分git输出.

我试图通过管道将git输出输出到Out-HostOut-Default,但是都无法正常工作.

这是我的代码...

 $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
 

这是我的控制台输出...

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

这是成绩单中记录的内容,请注意,某些git输出丢失了

**********************
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
**********************

解决方案

没有没有理由致电Out-Default-只需按原样使用git命令,您的问题就会消失:其stdout和stderr流都将被转录.

git默认将 status 信息写入 stderr ,并且-c-错误使用-c特别影响stderr输出,如底部.

以下示例说明了在脚本中捕获了stdout和stderr输出:

$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

在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.


Out-Default cmdlet的目的:

Out-Default 并非要从用户代码中调用.

相反,它只能由 PowerShell主机应用程序,包括PowerShell本身. 它使用 PowerShell的输出格式系统,并将其发送到主机进行显示.

它是公共cmdlet的原因是允许您对其进行覆盖以定义 custom 输出格式化程序,尽管这样做很少见. >

覆盖就像在会话中定义高级Out-Default函数一样简单,该函数必须具有相同的参数声明和管道绑定行为.如此答案的底部所示,您可以通过包装器(代理)功能来支撑此类功能. ).请注意,为了从函数产生可见的输出,必须将自定义格式的字符串发送到原始的Out-Default或使用 host API 进行打印(最简单的方法是Write-Host案子).


错误:

您对Out-Default的使用-尽管建议不正确-可以说仍然可以使用.

虽然这是Out-Default的讨论点,但鉴于不应直接调用它,所以Out-Host出现了相同的问题(与PowerShell Core 7.0.0-preview.6一样),并且出现了 是调用Out-Host的正当理由,即仅显式打印到显示器(这样做不会影响转录行为).

具体地说,如果显式使用Out-Host,则外部程序 stderr 输出不会意外地记录在成绩单中. (相比之下,PowerShell命令不会出现此问题.)

该问题已在此GitHub问题中报告.

I'm writing a script that will perform some git actions and I want to use Start-Transcript to monitor it. The transcript is however missing most of the git output.

I've tried to pipe the git output to both Out-Host and Out-Default but neither work.

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...

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

**********************
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
**********************

解决方案

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.

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.

The following example demonstrates that both stdout and stderr output are captured in the transcript:

$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:

--- 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 is not meant to be called from user code.

Instead, it is meant to be used only by PowerShell host applications, including PowerShell itself. It creates pretty-printed string representations of the output objects using PowerShell's output-formatting system and sends them to the host for display.

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.

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. You can scaffold such a function via a wrapper (proxy) function, as demonstrated in the bottom section of this answer). 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).


Bug:

Your use of Out-Default - though ill-advised - should arguably still have worked.

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).

Specifically, if you use Out-Host explicitly, stderr output from external programs is unexpectedly not recorded in the transcript. (By contrast, the problem doesn't surface with PowerShell commands.)

The problem has been reported in this GitHub issue.

这篇关于PowerShell脚本未捕获git输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆