如何从 PowerShell 写入标准错误,或捕获以下错误:
- 错误消息显示为错误(真正写入标准错误,以便 TeamCity 和 Octopus 将其视为错误)
- 没有堆栈跟踪垃圾扰乱我美丽、简洁的错误消息
这些年来,我一直通过抛出
错误或通过Write-Error
编写来生存,但我又累又老,在我的脚本中我只想查看一条简洁的错误消息。我一直在尝试 trap
、throw
、Write-Error
和 -ErrorAction
的每种组合,但没有可用:
try {
throw "error" # Sample code for a stack overflow. In the theater
# of your mind, imagine there is code here that does something real and useful
} catch {
Write-Error "An error occurred attempting to 'do something.' Have you tried rebooting?"
}
这是我想要看到的用户体验:
C:\> & .\Do-Something.ps1
An error occurred attempting to 'do something.' Have you tried rebooting?
C:\> ▏
相反,我得到:
C:\> & .\Do-Something.ps1
An error occurred attempting to 'do something.' Have you tried rebooting?
At line:1 char:1
+ Do-RealWork
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Do-RealWork
C:\> ▏
最佳答案
关于什么不起作用的前言:
设置
$ErrorView
preference variable$ErrorView
变量为'CategoryView'
导致 PowerShell 输出简洁的单行错误表示,但这种表示可能并不总是包含足够的信息,因为错误消息通常是不包括在内;从好的方面来说,文本传递到Throw "..."
被反射(reflect),但是相比之下,Write-Error
输出不包含任何特定信息,而'CategoryView'
已生效。同时PowerShell (Core) 7+现在通过新的
$ErrorView
默认为更简洁错误格式(在最简单的情况下仅打印错误消息)默认,ConciseView
,此输出在某些情况只是单行。
值得注意的是,如果错误发生在脚本(.*ps1
文件)或function
中,它仍然是多行来自脚本(包括配置文件脚本)的点源,在这种情况下,错误消息前面是报告脚本文件路径、源代码行和行号的附加行。
如果您的 PowerShell 代码是从控制台运行(使用控制台主机),使用 [Console]::Error.WriteLine()
,无条件写入外界的 stderr(标准错误流):
[Console]::Error.WriteLine("An error occurred ... Have you tried rebooting?")
注意:
这在非控制台主机(例如 PowerShell ISE)上不起作用。
[Console]::Error.WriteLine()
输出不会在控制台[1]中以红色打印。
遗憾的是,没有一种解决方案可以同时在 PowerShell 内部(跨主机)和其外部工作强>:
[Console]::Error.WriteLine()
,在为外部世界正确写入 stderr 时,无法在 PowerShell 内部捕获或抑制其输出,并且仅适用于 PowerShell 控制台主机.同样,
$host.ui.WriteErrorLine()
,即使适用于所有主机,它也是一种UI方法,也可以在PowerShell的流系统之外工作,因此它的输出也无法在PowerShell中捕获或抑制。
更重要的是,它不会写入外部世界的 stderr(在这方面它的行为类似于Write-Error
,见下文)。在 PowerShell 内部,仅限
Write-Error
写入 PowerShell 的错误流,因此可以捕获/抑制其输出。
然而,不幸的是,Write-Error
(除了噪音之外)不写入外部世界的stderr,除非,奇怪的是,stderr显式被重定向 - 请参阅this answer我的详细信息。
[1] Peter(OP本人)为此提供了一种解决方法:
[Console]::ForegroundColor = 'red'
[Console]::Error.WriteLine("An error occurred ... Have you tried rebooting?")
[Console]::ResetColor()
suneg's helpful answer为其提供了一个函数包装器。
幸运的是,当 PowerShell 检测到输出被重定向(到文件)时,它会自动忽略颜色代码。
关于powershell - 如何在没有附带堆栈跟踪的情况下在 PowerShell 中显示 'naked' 错误消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38064704/