系统学习 学习路径总入口:先选领域,再建立模型,最后用故障演练验证

版本信息最后核对:2026-10-25

区分终止与非终止错误,用 try/catch、错误流和退出码把失败路径写清楚

适用场景

脚本要区分“可恢复的失败”和“必须停下来的失败”,要把错误写进日志、返回给调用方,或在批处理中继续处理其他对象时使用。复杂的自动化脚本、发布脚本、计划任务和被其他程序调用的入口脚本都应该显式处理错误。

简单的一次性命令不需要套 try/catch;把每条命令都包起来只会掩盖真正的问题。先判断错误的类型和传播方式,再决定捕获粒度。

核心概念

5.1 与 7.x 差异

常用操作

# 1. 非终止错误必须显式 Stop 才能被 catch,finally 负责清理
PS C:\> try { Get-Content C:\missing.txt -ErrorAction Stop } catch { "捕获: $($_.Exception.Message)" } finally { '清理临时资源' }

# 2. 查看最近错误的完整记录;7.x 还可以直接用 Get-Error
PS C:\> $Error[0] | Format-List * -Force
PS C:\> Get-Error

# 3. 不想中断循环,但要把错误收集起来统一判断
PS C:\> Get-ChildItem C:\NoSuchDir -ErrorAction SilentlyContinue -ErrorVariable errs
PS C:\> if ($errs.Count -gt 0) { $errs[0].CategoryInfo }

# 4. 原生命令不抛 PowerShell 异常,必须检查退出码
PS C:\> git status
PS C:\> if ($LASTEXITCODE -ne 0) { throw "git 失败,退出码 $LASTEXITCODE" }

# 5. 临时把默认行为改成终止错误,结束后恢复原值
PS C:\> $old = $ErrorActionPreference
PS C:\> $ErrorActionPreference = 'Stop'
PS C:\> try { Get-Item C:\missing } catch { $_.FullyQualifiedErrorId }
PS C:\> $ErrorActionPreference = $old

# 6. 按异常类型分别处理,不要用空 catch 吞掉所有错误
PS C:\> try { [int]::Parse('abc') } catch [System.FormatException] { '格式错误' } catch { '其他错误' }

# 7. 7.4+ 可选:让原生命令非零退出码遵循 ErrorActionPreference
PS C:\> $PSNativeCommandUseErrorActionPreference = $true
PS C:\> $ErrorActionPreference = 'Stop'
PS C:\> try { git status } catch { "git failed: $($_.Exception.Message)" }

易错点

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. 为什么 try { Get-Item C:\missing } catch { } 没有进入 catch?
  2. -ErrorAction SilentlyContinue 和 -ErrorAction Ignore 有什么区别?
  3. 调用外部程序后,怎样判断它是否成功?
答案
  1. Get-Item 默认产生非终止错误,只写入错误流并继续,不会触发 catch;需要加 -ErrorAction Stop 或把 $ErrorActionPreference 设为 Stop。
  2. SilentlyContinue 不显示错误但仍写入 $Error 和 -ErrorVariable;Ignore 连错误记录都不产生,适合确定要完全忽略的场景。
  3. 检查 $LASTEXITCODE 是否为 0,并确认它是目标程序刚刚设置的;PowerShell cmdlet 的失败则看 $?、错误流或 -ErrorAction Stop。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令