如何从 PowerShell 脚本获取退出代码

Yos*_*shi 4 error-handling powershell try-catch exit-code

我正在尝试编写一个 PowerShell 脚本,每当我们的构建系统无法将 Docker 映像推送到 Docker Hub 时,该脚本都会发送 Slack 通知。如何检测并处理Process exited with code 1命令docker push?我已尝试以下操作,但未catch调用该块。

try {
  docker push $dockerImage;
}catch{
  #Send error details to Slack
}
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 5

  • Windows PowerShellPowerShell (Core) 直至版本 7.3.x中,外部程序(例如docker)的调用绝不会导致语句终止错误[1],您可以使用try/catch捕获该错误;类似地,外部程序的stderr输出(正确地)被 PowerShell视为错误输出,因此$ErrorActionPreference = 'Stop'对其没有影响(对于Windows PowerShell中的旧异常,请参阅此答案)。

    • PowerShell (Core) v7.4+中,可以通过$PSNativeCommandUseErrorActionPreference首选项变量选择与 PowerShell 的错误处理集成。

      • 如果将此变量设置为,则任何报告非零退出代码$true的外部程序调用都会自动触发PowerShell错误作为响应(无需显式检查),然后与 PowerShell 自己的错误处理集成。[2] 也就是说,当首选项变量设置为 时,任何报告非零退出代码的外部程序都将导致脚本终止(默认情况下致命)错误。 $LASTEXITCODE -ne 0
        $ErrorActionPreference'Stop'
    • 一般来说,请注意,如果 PowerShell 甚至无法启动命令,例如当您提供不存在的可执行文件名称或路径时,确实会发生语句终止 PowerShell 错误(可以使用/ 捕获)try;例如:catch

      try   { nosuchexe foo bar }
      catch { Write-Warning "Failed to invoke nosuchexe: $_" }
      
      Run Code Online (Sandbox Code Playgroud)
  • 自动变量反映最近执行的外部程序的进程$LASTEXITCODE退出代码。按照惯例,退出代码0表示成功,其他任何情况都表示错误情况

所以:

docker push $dockerImage
if ($LASTEXITCODE -ne 0) {
  #Send error details to Slack
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • 此答案提供了有关 PowerShell 中退出代码处理的更多信息。

[1] 唯一的例外是一个bug,存在于Windows PowerShell中,并且历史上出现在 PowerShell (Core) 直至不再受支持的 v7.1.x 中,其中重定向 stderr 输出2>*>)与$ErrorActionPreference = 'Stop'意外导致脚本的组合- 如果有实际的 stderr 输出,则终止错误 - 请参阅此答案

[2] 不幸的是,至少在 PowerShell 7.4.0-preview.6 之前,自动触发的 PowerShell 错误是一种非终止错误,而不是语句终止错误;后者更有意义,因为它允许有选择地用语句捕获它try- 请参阅GitHub Issue #18368