powershell - 如何在没有附带堆栈跟踪的情况下在 PowerShell 中显示 'naked' 错误消息?

标签 powershell error-handling stderr exit-code

如何从 PowerShell 写入标准错误,或捕获以下错误:

  • 错误消息显示为错误(真正写入标准错误,以便 TeamCity 和 Octopus 将其视为错误)
  • 没有堆栈跟踪垃圾扰乱我美丽、简洁的错误消息

这些年来,我一直通过抛出错误或通过Write-Error编写来生存,但我又累又老,在我的脚本中我只想查看一条简洁的错误消息。我一直在尝试 trapthrowWrite-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/

相关文章:

Powershell v2.0 模块 : Default Load Path (User/Windows system folder)?

sql - 如何格式化 SQL 中的字符串,以便在 Powershell 中正确解释它?

python - 是否可以将 .py 和 .ps1 脚本合并到 .exe 中?

c# - 是否有可能捕获您无法处理的异常(在 C# 中)?

python - 如何抑制 web.py 输出?

powershell - 使用 "Put"参数 : "0" on Win32_TerminalServiceSetting 调用 ""的异常

PHP 核心警告 - yii\base\ErrorException - Yii2

c# - XMLTextWriter C#,未找到标准xml的数据

错误的 fprintf 的 C++ 等价物

java - System.out.println 不在 Windows Linux 子系统 bash 中打印