Bash中运行可能失败的命令不中断脚本且获取退出码的方案
Bash 捕获命令退出码且不触发异常退出的最优实现
最简通用写法
最语义清晰、无冗余逻辑的实现方式如下:
# 初始化退出码为默认成功值(0) test_exit_code=0 # 执行目标命令,命令失败时更新退出码为实际值 docker exec $CONTAINER_NAME npm test || test_exit_code=$? # 后续命令正常执行 echo "copying unit test result file to host" docker cp $CONTAINER_NAME:/home/test/test-results.xml . exit $test_exit_code
写法说明
- 该写法天然适配开启了
set -e的脚本环境:Bash规则明确规定,||左侧的命令执行失败不会触发set -e强制退出,完全不需要临时修改全局错误配置 - 语义直白无歧义:默认命令执行成功,仅当命令报错时才更新退出码变量,无需额外注释就能让其他开发者快速理解逻辑
- 不存在原
&&/||简写的逻辑漏洞:不会因为中间操作失败获取到错误的退出码
可复用封装写法
如果需要频繁使用该能力,可以封装为通用工具函数,调用处语义更清晰:
# 通用工具函数:执行传入的命令,返回命令的退出码,不会触发set -e退出 run_capture_exit_code() { local exit_code=0 "$@" || exit_code=$? return $exit_code } # 调用示例 run_capture_exit_code docker exec $CONTAINER_NAME npm test test_exit_code=$? # 后续逻辑不变 echo "copying unit test result file to host" docker cp $CONTAINER_NAME:/home/test/test-results.xml . exit $test_exit_code
与原有实现的优势对比
- 对比临时修改
set配置的写法:无需修改全局错误退出规则,不会出现漏写set -e导致后续异常无法被捕获的隐患 - 对比
if分支写法:没有冗余的分支结构,代码更简洁 - 对比
&&/||简写写法:逻辑完全无歧义,不存在中间操作出错导致退出码错误的问题,不需要额外注释说明逻辑
内容的提问来源于stack exchange,提问作者Val Kornea
相关产品推荐
相关产品推荐

