在PowerShell中抑制Git命令的输出

7
作为我正在运行的脚本的一部分,我使用"git clean -fd"命令。它通常会输出清理掉的一堆文件,我想要禁止该输出。 我尝试过“git clean -fd | Out-Null”,但似乎没有起作用。在搜索后没有找到任何可以禁止输出的选项,那么是否有其他 PowerShell 方法可用?或者是我做错了什么?值得注意的是,PowerShell 脚本本身是从 ".bat" 文件中执行的。

参见:https://dev59.com/2LXna4cB1Zd3GeqPKWrG#57316495 - jessehouwing
2个回答

8

phd's helpful answer提供了最佳的解决方案。

至于为什么... | Out-Null无效:

Out-Null仅抑制来自外部程序(例如git)的stdout输出,而不是stderr输出。

git和许多CLI(控制台/终端程序)一样,使用stderr流不仅报告错误,还用于状态信息 - 基本上是任何非数据内容。

要抑制stdoutstderr输出,请使用*> $null

git clean -fd *> $null

注意:*> $null 抑制了所有输出流;而外部程序只有2个(stdout和stderr),将*>$null应用于PowerShell本机命令会使所有6个输出流静音。

有关更多信息,请参见关于重定向


可选阅读:选择性从外部程序重定向流:

根据nmbell的反馈,可以进行以下改进:

  • >$null(或1>$null)可用于有选择性地抑制stdout输出,这与| Out-Null的效果相同。

  • 2>$null可用于有选择性地抑制stderr输出。

  • 如上所述,*>$null会使所有流静音。

当然,除了使用$null抑制输出外,重定向目标也可以是文件(名称或路径)。

注意:

  • PowerShell在其管道中逐行处理外部程序的输出。如果输出被捕获到一个变量中($out = ...)并且包含2行或更多行,则存储为行(字符串)的数组([object[]])。

  • PowerShell只与外部程序使用文本(字符串)进行通信,无论是发送还是接收数据,这意味着可能会涉及字符编码问题。

  • 有关这两个方面的更多信息,请参见this answer


带有示例的场景:

设置:

# Construct a platform-appropriate command, stored in a script block ({ ... }) 
# that calls an external program (the platform-native shell) that outputs
# 1 line of stdout and 1 line of stderr output each, and can later be 
# invoked with `&`, the call operator.
$externalCmd = if ($env:OS -eq 'Windows_NT') {     # Windows
                 { cmd /c 'echo out & echo err >&2' } 
               } else {                            # Unix (macOS, Linux)
                 { sh -c 'echo out; echo err >&2' } 
               }

捕获标准输出,通过stderr传递:

PS> $captured = & $externalCmd; "Captured: $captured"
err            # Stderr output was *passed through*
Captured: out  # Captured stdout output.

使用2>$null捕获标准输出,禁止错误输出:

PS> $captured = & $externalCmd 2>$null; "Captured: $captured"
Captured: out  # Captured stdout output - stderr output was suppressed.

使用*>&1同时捕获stdout和stderr:

PS> $captured = & $externalCmd *>&1 | % ToString; "Captured: $captured"
Captured: out err  # *Combined* stdout and stderr output.

注意:

  • % ToStringForEach-Object ToString 的简写形式,它在每个输出对象上调用 .ToString() 方法,确保 PowerShell 封装的 System.Management.Automation.ErrorRecord 实例中的 stderr 行被转换回 字符串
  • $captured 接收一个由两个元素组成的 数组 ([object[]]) - 分别包含 stdout 和 stderr 行;在本例中,它是 PowerShell 的字符串插值 将它们转换为单行、以空格分隔的字符串。

仅捕获标准错误流,抑制标准输出流:

PS> $captured = 
      & $externalCmd *>&1 | 
        ? { $_ -is [System.Management.Automation.ErrorRecord] } | 
          % ToString; "Captured: $captured"
Captured: err  # Captured stderr output *only*.

注意:

  • ? { $_ -is [System.Management.Automation.ErrorRecord] }Where-Object { $_ -is [System.Management.Automation.ErrorRecord] } 的缩写形式,它只传递标准错误行(通过测试包装类型)并再次使用% ToString将其转换回字符串。

  • 这种技术既不明显也不方便; GitHub suggestion #4332 提出了一种语法,例如2> variable:stderr 以支持将流重定向到变量,例如在本例中的$stderr


谢谢,@nmbell:我已经将您的反馈整合到答案中,并进行了扩充;请查看新添加的底部部分。 - mklement0

5
只需添加选项-q
git clean -fdq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接