提问人:sbi 提问时间:8/15/2012 最后编辑:sbi 更新时间:9/5/2022 访问量:55716
如何禁止 PowerShell 中的标准错误输出?
How do I suppress standard error output in PowerShell?
问:
在自动执行某些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 info $url 2>&1 | out-null
这就像一个魅力。
评论
$() | out-null
$( svn info $url 2>&
$( svn info $url ) 2>&1 | out-null
2>&1
$(svn info $url) | out-null
2>&1
)
2>&1
git commit
也可以这样做:
svn info $url *> $null
评论
投票的答案为我生成了一个错误。解决方案最终如下:
cmd /c "MyProgram MyArguments 2>&1" | Out-Null
评论
PSNotApplyErrorActionToStderr
如果只想抑制标准误差,请使用:
svn info $url 2>$null
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
}
您自己的答案有效地解决了重定向问题。
Steven Penny 的回答建议,即抑制所有输出流作为一种方便的替代方案 - 它消除了对 的需求,我通常建议将其替换为 - 请参阅此答案。*>$null
Out-Null
$null = ...
但是,您问题中的代码还有另一个问题:
虽然它可能适用于您的特定命令,但不幸的是,$?
并不是外部程序是否成功的可靠指标 - 请改用$LASTEXITCODE -eq 0,因为 - 由于 PowerShell Core 7.0.0-preview.3 的错误,在 GitHub 上报告 此处 - 最终可能会反映,即使 是(明确表示成功)。
$?
$false
$LASTEXITCODE
0
至于你在问题中尝试了什么:
svn info $url | out-null 2>&1 # WRONG
只有成功输出才会发送到管道(外部程序的 stdout 输出将发送到 PowerShell 的成功输出流)。
重定向(例如)作用于管道中的单个命令,而不是整个管道。
2>&1
因此,如果产生 stderr 输出,它会直接打印到主机(控制台)上 - 永远不会看到它。
svn info $url
Out-Null
评论
需要注意的重要一点是,某些 Powershell cmdlet 在这些方法中无法正确运行。这样的例子是,无论你使用什么技巧,它都会在失败时输出错误:Get-ADUser
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
在这些情况下,您将不得不创建/阻止,或寻找其他替代方案(例如,检查AD对象是否存在;如何避免丑陋的错误消息?try
catch
希望这能为某人省去一些无用的挠头。
评论