Ste*_*own 2 error-handling powershell stderr
我试图通过 PowerShell 运行命令并捕获其 stdout 和 stderr而不将它们打印在屏幕上(命令非常嘈杂并污染控制台)。
我想捕获变量中的 stdout 和 stderr,然后在找到特定字符串时抛出异常。
我的逻辑似乎正常工作,我可以在我期望的时候使 cmdlet 失败/通过,但是输出与我的期望不匹配,而不是返回我指定的错误消息,我得到的是我认为是 stderr 的内容命令代替?
(为了便于阅读而进行了简化)
第一个 cmdlet:
function Test-Validation
{
[CmdletBinding()]
param(
[Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 0)]
[Array]
$ValidExitCodes = @(0),
[Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 1)]
[bool]
$FailOnWarning = $true
)
$Validation = . pdk validate 2>&1
if ($LASTEXITCODE -notin $ValidExitCodes)
{
throw "Module validation has failed. Exit code: $($LASTEXITCODE)."
}
$Warnings = $Validation -match 'pdk \(WARNING\)'
if (($Warnings) -and ($FailOnWarning -eq $true))
{
throw "Module validation contains warnings.`n$Warnings"
}
Write-Verbose "Module successfully passed validation"
}
Run Code Online (Sandbox Code Playgroud)
由第二个 cmdlet 调用:
function Test-Module
{
[CmdletBinding()]
param
()
try
{
Test-Validation
}
catch
{
throw "$($_.Exception.Message)"
}
try
{
Test-Unit
}
catch
{
throw "$($_.Exception.Message)"
}
}
Run Code Online (Sandbox Code Playgroud)
PS /opt/script/test/> Test-Module
Exception: /opt/script/test/Test-Module.ps1:13:9
Line |
13 | throw "$($_.Exception.Message)"
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Module validation has failed. Exit code: 1.
Run Code Online (Sandbox Code Playgroud)
PS /opt/script/test/> Test-Module
Exception: /opt/script/test/Test-Module.ps1:13:9
Line |
13 | throw "$($_.Exception.Message)"
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| pdk (INFO): Using Ruby 2.5.8
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它似乎返回我正在运行的命令 (pdk) 的输出,而不是"Module validation has failed. Exit code: $($LASTEXITCODE)."我在 Test-Validation cmdlet 中定义的消息。
为什么我没有收到我想要的错误消息,有什么方法可以实现我想要的结果吗?除了任何代码建议之外,我非常感谢任何有关我的问题的进一步阅读,以便我可以更好地理解这些事情。
注意:这是由 PoSh Core 在 MacOS 上运行的
您的症状意味着该$ErrorActionPreference = 'Stop'功能在函数执行时有效
Test-Validation。(暂时)将其设置'Continue'为解决您的问题 - 在未来的版本中希望不再需要(见下文)。
观察到的行为的原因是,在 Windows PowerShell 和 PowerShell (Coe) 7.1之前的版本中,使用错误流重定向( ) 使 PowerShell通过 PowerShell 的错误流路由外部程序的 stderr 输出2>(请参阅about_Redirection),$ErrorActionPreference = 'Stop'因此一旦收到第一个 stderr 行,就会抛出脚本终止错误。
这种行为是不幸的,因为外部程序的 stderr 输出不能被假定为表示错误条件,因为外部程序实际上使用 stderr(标准错误流)来处理除 data 之外的任何内容,例如,其中包括状态信息。
PowerShell 7.2 及更高版本更好地改变了这种行为:stderr 输出不再通过 PowerShell 的错误流路由,这意味着:
(幸运的是)标准错误行不再收集在自动$Error变量中。
首选项变量$ErrorActionPreference不再对外部程序的 stderr 输出产生任何影响。
自动变量指示最近执行的语句的$?成功状态,不再错误地设置为$false进程退出代码,0 并且也恰好有 stderr 输出 - 但请注意,您始终可以推断外部的成功与失败通过自动变量进行编程$LASTEXITCODE
| 归档时间: |
|
| 查看次数: |
1902 次 |
| 最近记录: |