Svn 如何抑制PowerShell中的标准错误输出?

Svn 如何抑制PowerShell中的标准错误输出?,svn,powershell,io-redirection,Svn,Powershell,Io Redirection,在自动化某些SVN任务的PowerShell脚本中,我具有以下功能: function SvnUrlExists($url) { svn info $url | out-null 2>&1 return $? } 因为这显式地测试了是否存在某个SVN存储库URL,所以我对任何错误输出都不感兴趣。然而,尽管我在PowerShell中找到了所有关于重定向stderr的信息,建议2>&1将其重定向到stdout,但仍会输出一条错误消息: svn: warning: W17000

在自动化某些SVN任务的PowerShell脚本中,我具有以下功能:

function SvnUrlExists($url)
{
  svn info $url | out-null 2>&1
  return $?
}
因为这显式地测试了是否存在某个SVN存储库URL,所以我对任何错误输出都不感兴趣。然而,尽管我在PowerShell中找到了所有关于重定向
stderr
的信息,建议
2>&1
将其重定向到
stdout
,但仍会输出一条错误消息:

svn: warning: W170000: URL 'blahblah' non-existent in revision 26762 svn: E200009: Could not display info for all targets because some targets don't exist svn:警告:W170000:修订版26762中不存在URL“blahblah” svn:E200009:无法显示所有目标的信息,因为某些目标不存在 不幸的是,这严重扰乱了我脚本的输出


我做错了什么?我应该如何抑制这个错误输出?

以防万一其他人在谷歌上搜索与我类似的术语:

在我用额头敲打了几个小时之后,我当然在这里发布问题后几分钟内找到了解决方案:

svn info $url 2>&1 | out-null
这很有魅力

也可以这样做:

svn info $url *> $null


投票后的答案为我生成了一个错误。最终的解决方案如下:

cmd /c "MyProgram MyArguments 2>&1" | Out-Null

如果要仅抑制标准错误,请使用:

svn info $url 2>$null
tl;dr

function SvnUrlExists($url)
{

  # Suppress all output streams (external stdout and stderr in this case)
  # To suppress stderr output only, use 2>$null
  svn info $url *>$null 

  # For predictable results with external programs, 
  # infer success from the *process exit code*, not from the automatic $? variable.
  # See https://github.com/PowerShell/PowerShell/issues/10512
  $LASTEXITCODE -eq 0
}

您的解决方案有效地解决了重定向问题

建议
*>$null
,即作为一种方便的替代方案抑制所有输出流-它消除了
输出null
的需要,我通常建议将其替换为
$null=…
-请参阅

但是,问题中的代码还有另一个问题:

svn info $url | out-null 2>&1  # WRONG
虽然它可以与您的特定命令一起使用,
$?
,但不幸的是,它不是外部程序成功与否的可靠指标
-请改用
$LASTEXITCODE-eq 0
,因为-由于PowerShell Core 7.0-preview.3中的错误,在GitHub上报告-
$?
最终可能会反映
$false
,即使
$LASTEXITCODE
0
(明确表示成功)

  • 更新:如果且当名为
    PSNotApplyErrorActionToStderr
    的7.2版之前版本成为官方功能时,此问题将消失-有关更多信息,请参阅

至于你在问题中尝试了什么

svn info $url | out-null 2>&1  # WRONG
  • 只有成功输出被发送到管道(外部程序的标准输出被发送到PowerShell的成功输出)

  • 例如
    2>&1
    作用于管道中的单个命令,而不是整个管道

  • 因此,如果
    svn info$url
    生成stderr输出,它将直接打印到主机(控制台)-
    Out Null
    从未看到它


此外,如果您有一个更大的命令,您可以将它包装在
$()| out null
中以获得相同的效果。例如:
$(svn info$url 2>&
)| out null`。当命令很长时,我会这样做,或者我需要在脚本中将其打断几行。@Nick:啊,谢谢。但是,它不是必须是
$(svn info$url)2>&1 | out null
?(注意
2>&1
的位置)哦,哇,我完全误读了你的帖子。是的,它应该是
$(svn info$url)| out null
。这取决于您希望在哪里对
2>&1
进行错误检查。我不能不测试它就说,但我认为它是在
内部还是外部并不重要。实际上,您可以完全关闭
2>&1
,就像我说的,不进行测试,我不能确定。它可以工作,但如果在脚本中使用它,将导致错误停止脚本。这可能不是预期的副作用。我之所以会遇到这个问题,是因为我有一个
git commit
,在通过PowerShell运行时无法访问stfu。。。我非常接近让PS调用'git bash'而不是处理git的东西。至少我可以相信bash会使内容静音。或者svn info$url 2>$null仅适用于stderr。如果您有$ErrorActionPreference='stop',将stderr重定向到stdout仍将生成错误并停止脚本执行。但如果不将stderr重定向到stdout,则不会发生错误。奇怪@拉法克斯:真的很奇怪;这是一个bug:任何跟踪它的人都可以看到,它被复制到了v7.1.0版(仍在预览中),可能隐藏在标记
PSNotApplyErrorActionToStderr
“重定向(如2>&1)作用于管道中的单个命令,而不是整个管道。”-这就是解决我遇到的问题的原因。