为何PowerShell作业未按预期失败?是否必须用try/catch?
问题分析与解答
为什么第一种情况作业未失败?
这是PowerShell作业对脚本块执行状态的判断逻辑导致的:
- 当脚本块包含多条语句时,默认
$ErrorActionPreference = Continue的情况下,即使执行过程中出现错误(比如调用未定义的NonsenseCmd触发CommandNotFoundException),只要脚本块能完成全部语句的执行(错误不会终止脚本),作业状态就会被标记为Completed。这里的$SomeVar = ""是成功执行的,后续的错误仅输出错误信息,但脚本块并未提前终止,因此作业显示完成。 - 当脚本块只有单条语句时,PowerShell会将这条语句的执行结果直接作为作业的执行结果。如果这条语句失败(比如命令不存在),作业状态就会被标记为
Failed,因为整个脚本块的执行等同于这条命令的执行结果。
是否必须使用try/catch?
不是必须的,有多种方式可以让作业在出现错误时标记为Failed:
- 方法1:修改错误处理偏好
在脚本块开头设置$ErrorActionPreference = Stop,这样任何错误都会被转为终止错误,直接终止脚本块执行并标记作业为失败:$MyScript = { $ErrorActionPreference = Stop $SomeVar = "" NonsenseCmd } Start-Job -ScriptBlock $MyScript | Wait-Job | Get-Job - 方法2:使用try/catch捕获并重新抛出
就是你当前使用的方法,通过捕获异常后throw,主动触发终止错误,让作业状态变为失败。 - 方法3:局部设置错误偏好
如果不想全局修改错误偏好,可以在目标命令前临时设置:$MyScript = { $SomeVar = "" $ErrorActionPreference = Stop NonsenseCmd }
需要注意的是,默认情况下PowerShell的错误分为终止错误和非终止错误,调用未定义命令的错误属于终止错误,但在Continue偏好下,脚本会继续执行,因此作业不会标记为失败。只有让错误终止脚本执行,作业才会显示为Failed。
内容的提问来源于stack exchange,提问作者foxtrott79
相关产品推荐
相关产品推荐

