[英]How do I suppress standard error output in PowerShell?
In a PowerShell script automating some SVN tasks I have the following function:在自动化一些 SVN 任务的 PowerShell 脚本中,我有以下 function:
function SvnUrlExists($url)
{
svn info $url | out-null 2>&1
return $?
}
Since this explicitly tests whether some SVN repository URL exists, I am not interested at all in any error output.由于这明确测试是否存在某些 SVN 存储库 URL,因此我对任何错误 output 都不感兴趣。 However, despite everything I found about redirecting stderr
in PowerShell suggesting 2>&1
to redirect it to stdout
, this still outputs an error message :然而,尽管我发现了关于在 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
Unfortunately, this severely messes up the output of my script.不幸的是,这严重破坏了我脚本的 output。
What am I doing wrong, and how should I suppress this error output?我做错了什么,我应该如何抑制这个错误 output?
Just in case someone else googles for similar terms as I did:以防万一其他人像我一样用谷歌搜索类似的术语:
After I have been banging my forehead against this for hours, of course I found the solution within minutes after posting the question here:在我用我的额头敲打了几个小时之后,当然我在在这里发布问题后几分钟内找到了解决方案:
svn info $url 2>&1 | out-null
This works like a charm.这就像一个魅力。
如果要抑制的唯一标准错误,使用:
svn info $url 2>$null
One can also do this:也可以这样做:
svn info $url *> $null
See Suppress console output in PowerShell请参阅在 PowerShell 中抑制控制台输出
The voted answer generates an error for me.投票的答案对我产生了错误。 The solution ended up being the following:解决方案最终如下:
cmd /c "MyProgram MyArguments 2>&1" | Out-Null
tl;dr tl;博士
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
}
Your own answer effectively addresses the redirection issue .您自己的回答有效地解决了重定向问题。
Steven Penny's answer proposes *>$null
, ie suppressing all output streams as a convenient alternative - it obviates the need for Out-Null
, which I generally suggest replacing with $null = ...
- see this answer . Steven Penny 的回答提出*>$null
,即抑制所有输出流作为一种方便的替代方案 - 它消除了对Out-Null
的需要,我通常建议用$null = ...
替换它 - 请参阅此答案。
However, there's another problem with the code in your question:但是,您问题中的代码还有另一个问题:
While it may work with your particular command, $?
虽然它可能适用于您的特定命令,但$?
, unfortunately, is not a robust indicator of whether an external program succeeded or not - use $LASTEXITCODE -eq 0
instead, because - due to a bug as of PowerShell Core 7.0.0-preview.3, reported on GitHub here - $?
不幸的是,不是一个外部程序成功与否稳健指标-使用$LASTEXITCODE -eq 0
代替,因为-由于错误的PowerShell核心7.0.0-preview.3的报告在GitHub上这儿- $?
can end up reflecting $false
even when $LASTEXITCODE
is 0
(unequivocally signaling success).即使$LASTEXITCODE
为0
(明确表示成功)也可能最终反映$false
。
PSNotApplyErrorActionToStderr
becomes an official feature, this problem will go away - see this answer for more information.更新:如果名为PSNotApplyErrorActionToStderr
的 v7.2 之前的实验性功能成为正式功能,则此问题将消失 - 请参阅此答案以获取更多信息。As for what you tried in your question:至于你在你的问题中尝试了什么:
svn info $url | out-null 2>&1 # WRONG
Only success output is sent through to the pipeline ( stdout output from external programs is sent to PowerShell's success output stream ).只有成功输出被发送到管道(来自外部程序的stdout输出被发送到 PowerShell 的成功输出流)。
Redirections such as 2>&1
act on individual commands in a pipeline, not the pipeline as a whole . 重定向如2>&1
在管道,而不是管道作为一个整体作用于各个命令。
Therefore, if svn info $url
produces stderr output, it prints straight to the host (console) - Out-Null
never sees it.因此,如果svn info $url
产生stderr输出,它会直接打印到主机(控制台)- Out-Null
永远不会看到它。
Important to note is that some Powershell cmdlets do not behave correctly with these methods.需要注意的重要一点是,某些 Powershell cmdlet 在这些方法中无法正常运行。 Such an example is Get-ADUser
which will output the error in case of failure no matter what trick you use:这样的例子是Get-ADUser
它将 output 在失败的情况下错误,无论你使用什么技巧:
PS C:\Temp\2022-09-05T08-28-46_oexvijzd.tfq> Get-ADUser -Identity "CN=administrator,DC=acme,DC=internal" 2>&1 | Out-Null
Get-ADUser : Directory object not found
At line:1 char:1
+ Get-ADUser -Identity "CN=administrator,DC=acme,DC=internal" 2>&1 | Ou ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (CN=administrator,DC=acme,DC=internal:ADUser) [Get-ADUser], ADIdentityNotFoundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
PS C:\Temp\2022-09-05T08-28-46_oexvijzd.tfq> Get-ADUser -Identity "CN=administrator,DC=acme,DC=internal" *>$null
Get-ADUser : Directory object not found
At line:1 char:1
+ Get-ADUser -Identity "CN=administrator,DC=acme,DC=internal" *>$null
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (CN=administrator,DC=acme,DC=internal:ADUser) [Get-ADUser], ADIdentityNotFoundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
PS C:\Temp\2022-09-05T08-28-46_oexvijzd.tfq> Get-ADUser -Identity "CN=administrator,DC=acme,DC=internal" *>$null | Out-Null *>$null
Get-ADUser : Directory object not found
At line:1 char:1
+ Get-ADUser -Identity "CN=administrator,DC=acme,DC=internal" *>$null | ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (CN=administrator,DC=acme,DC=internal:ADUser) [Get-ADUser], ADIdentityNotFoundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
In these cases, you will have to make try
/ catch
blocks, or find other alternatives (eg Checking for the existence of an AD object; how do I avoid an ugly error message? ).在这些情况下,您将不得不创建try
/ catch
块,或寻找其他替代方案(例如检查 AD object 的存在;如何避免丑陋的错误消息? )。
Hope this will save someone some unproductive head scratching.希望这可以节省一些非生产性的挠头。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.