在 PowerShell 中禁止输出 Git 命令



作为脚本的一部分,我正在运行git clean -fd. 它通常会输出一堆经过清理的文件。我想抑制此输出。

我尝试了git clean -fd | Out-Null但它似乎不起作用。 谷歌搜索没有返回任何选项供git抑制输出,那么我可以使用另一种PowerShell方法吗?还是我做错了什么? 值得注意的是,PowerShell 脚本本身是从.bat文件中执行的。

博士的有用答案为手头的案例提供了最佳解决方案。

至于为什么... | Out-Null没有效果:

Out-Null只抑制来自外部程序(如git(的stdout输出,而不抑制 stderr 输出

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

要抑制标准输出和标准输出,请使用*> $null

git clean -fd *> $null

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

有关详细信息,请参阅about_Redirection。


可选阅读:来自外部程序的选择性流重定向:

基于nmbell的反馈:

  • >$null(或1>$null(可用于有选择地抑制标准输出输出,这实际上与| Out-Null相同。

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

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

当然,重定向目标也可能是文件(名称或路径(,而不是用于抑制输出的$null

注意:

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

  • PowerShell 仅在发送和接收数据时与外部程序"说出文本"(使用字符串(,这意味着字符编码问题可能会发挥作用。

  • 有关这两个方面的更多信息,请参阅此答案。


场景及示例

设置:

# 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' } 
}

Capture stdout,通过 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

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

注意:

  • % ToStringForEach-Object ToString的缩写,它在每个输出对象上调用.ToString()方法,从而确保 PowerShell 包装stderr行的System.Management.Automation.ErrorRecord实例转换回字符串
  • $captured接收一个 2 元素数组([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] }的缩写,它只通过 stderr 行 - 通过正在测试的包装器类型识别 - 通过,% ToString再次将它们转换回字符串。

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

只需添加选项-q

git clean -fdq

最新更新