Pas*_*ger 19 git powershell git-clone
git clone它的输出写到stderr作为记录在这里.我可以使用以下命令重定向它:
git clone https://myrepo c:\repo 2>&1
Run Code Online (Sandbox Code Playgroud)
但是这会将所有输出(包括错误)重定向stderr到stdout.有没有办法将进度消息重定向到stdout但仍然写入错误消息stderr.
Von*_*onC 12
MingW更新提供了一种新方法来处理Git 2.15.x / 2.16(Q1 2018)的重定向
请参阅Johannes Schindelin()的commit b2f5571,commit 1a172e4和commit 3f94442(2017年11月1日)。(通过合并JUNIOÇ滨野- -在提交421f21c,2017年11月9日)dscho
gitster
mingw:添加实验性功能以重定向标准手柄特别是从诸如Visual Studio的Team Explorer之类的应用程序调用Git时,正确关闭stdin / stdout / stderr很重要。
但是,在Windows上生成进程时,如果要使用它们,则必须将这些句柄标记为可继承,但是该标志是全局标志,并且可能很好地被其他生成的进程使用,这些进程随后不知道关闭这些句柄。让我们介绍一组环境变量(
GIT_REDIRECT_STDIN和朋友),这些变量指定文件的路径,或者甚至更好的命名管道(类似于Unix套接字),并由生成的Git进程使用。
这有助于解决上述问题:启动时将以不可继承的方式打开那些命名管道,并且不会传递任何句柄(因此,任何派生的子代都无需关闭继承的句柄)。从v2.11.0(2)开始,Git for Windows附带了此功能(标记为实验性),因此在此期间已经进行了一些认真的测试。
在Git的文档现在包括:
GIT_REDIRECT_STDIN:
GIT_REDIRECT_STDOUT:
GIT_REDIRECT_STDERR:
Run Code Online (Sandbox Code Playgroud)
仅限Windows:允许将标准输入/输出/错误句柄重定向到环境变量指定的路径。这在多线程应用程序中特别有用,在这种情况下,不能通过标准方式传递标准句柄,
CreateProcess()因为这将要求将句柄标记为可继承(因此,每个生成的进程都将继承它们,可能会阻止常规的Git操作)。主要的预期用例是使用命名管道进行通信(例如
\\.\pipe\my-git-stdin-123)。
它添加了:
mingw:可以选择通过同一句柄重定向stderr / stdout
2>&1在Powershell和Unix Shell中,“ ”表示stderr被重定向到stdout已经写入的同一句柄。让我们使用此特殊值与
GIT_REDIRECT_STDERR和允许相同的技巧GIT_REDIRECT_STDOUT:如果前者的值为2>&1,stderr则将简单地写入与相同的句柄stdout。该功能由Jeff Hostetler建议。
用法示例:$env:GIT_REDIRECT_STDERR = '2>&1'
mkl*_*nt0 12
一般来说:
控制台(终端)应用程序- 无论是在 Windows 上还是在类 Unix 平台上 - 都只有两个输出流可供使用:
因此,您不能也不应该根据 stderr 输出的存在来推断成功与失败。
相反,您必须仅依赖应用程序的进程退出代码:
0表示成功在PowerShell中,进程退出代码反映在自动变量中$LASTEXITCODE。
具体来说,这意味着:
给定gitstderr 输出行,您无法推断它们是否表示错误消息或其他类型的非数据信息,例如git经常使用的进度或状态消息。
git将其 stderr 输出明确重定向到 stdout(通过在 PowerShell 中将环境变量设置GIT_REDIRECT_STDERR为 string 2>&1; $env:GIT_REDIRECT_STDERR = '2>&1')并没有帮助,因为错误消息和进度/状态消息都会发送到那里。如前所述,您应该仅从非零退出代码推断失败。
务实的方法是执行以下操作:
# Invoke git and capture both its stdout and stderr streams, as strings.
$result = git clone https://myrepo c:\repo 2>&1 | % ToString
# Throw an error, if git indicated failure.
if ($LASTEXITCODE) { Throw "git failed (exit code: $LASTEXITCODE):`n$($result -join "`n")" }
# Output the captured result, as an array of lines.
$result
Run Code Online (Sandbox Code Playgroud)
笔记:
| % ToString(%是ForEach-Object) 的缩写,确保仅输出字符串2,前提是重定向到 ( >) 的 stderr 行(通过流 )成功输出流 ( &1) 包装在[System.Management.Automation.ErrorRecord]实例中。
[System.Management.Automation.ErrorRecord]打印;相比之下,Windows PowerShell会像 PowerShell 错误一样打印它们。2>&1在 PowerShell 版本高达 7.1 中可能会产生意想不到的副作用 - 请参阅此答案以获取背景信息。
该 RFC 草案的主题是更好地将外部程序调用集成到 PowerShell 的错误处理中,特别是在遇到非零退出代码时可以选择自动中止执行。
小智 9
我使用此脚本运行git命令。由于git即使成功也会写入stderr(例如,同步时拉入),因此这可以处理这些情况并写出输出的第一行,这通常是您需要知道的。
<#
.Synopsis
Invoke git, handling its quirky stderr that isn't error
.Outputs
Git messages, and lastly the exit code
.Example
Invoke-Git push
.Example
Invoke-Git "add ."
#>
function Invoke-Git
{
param(
[Parameter(Mandatory)]
[string] $Command )
try {
$exit = 0
$path = [System.IO.Path]::GetTempFileName()
Invoke-Expression "git $Command 2> $path"
$exit = $LASTEXITCODE
if ( $exit -gt 0 )
{
Write-Error (Get-Content $path).ToString()
}
else
{
Get-Content $path | Select-Object -First 1
}
$exit
}
catch
{
Write-Host "Error: $_`n$($_.ScriptStackTrace)"
}
finally
{
if ( Test-Path $path )
{
Remove-Item $path
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 9
我只是想补充一点,如果像我一样,您更关心 stderr 中的错误且仅错误,并且不关心任何进展,那么有一个非常简单的解决方法 - 您只需添加 -命令的安静(或 -q)。
这告诉 git 完全停止报告进度,除非发生实际错误。
| 归档时间: |
|
| 查看次数: |
6339 次 |
| 最近记录: |