在zsh脚本中捕获错误时获取错误信息及行号的方法
zsh脚本错误诊断:捕获错误信息、行号及变量值
核心问题梳理
- 脚本内整数除零会触发
err_return导致退出,但默认不输出zsh: division by 0这类错误提示 - 浮点数除零不会触发错误返回码,脚本会继续执行,仅将运算结果设为
inf或nan - 当前EXIT陷阱仅能打印变量,无法捕获错误原因与发生行号
解决方案
1. 捕获错误信息与行号
- 改用
ERR陷阱替代EXIT陷阱,错误发生时立即触发诊断逻辑 - 保留
set -o errexit(即err_return)确保错误时终止脚本 - 利用
$LINENO获取错误行号,$?获取错误码,通过zsh内置变量ZSH_ERROR_MSG获取错误描述
2. 处理浮点数除零的特殊情况
zsh对浮点数除零不会主动抛出错误,需手动检查运算结果,若为inf或nan则主动触发错误,让陷阱捕获。
修改后的测试脚本
#!/usr/bin/zsh # 错误诊断增强版脚本 set -o errexit set -o nounset # ERR陷阱:错误发生时触发诊断,$1传入错误行号 trap 'err.diagnostics $LINENO' ERR function err.diagnostics { local err_line=$1 local err_code=$? local DATE=$(date +"%A, %b %d, %H:%M:%S") printf '**************\n' printf '错误发生时间:%s\n' "$DATE" printf '错误行号:%d\n' "$err_line" printf '错误码:%d\n' "$err_code" printf '错误原因:%s\n' "$ZSH_ERROR_MSG" printf '当前变量值:\n' printf ' A: %f \n B: %d \n C: %f \n D: %d \n Z: %d \n' "$A" "$B" "$C" "$D" "$Z" printf '**************\n' } function check_float_result { local result=$1 if [[ "$result" == inf || "$result" == nan ]]; then ZSH_ERROR_MSG="浮点数运算错误:结果为$result" return 1 fi } function do_stuff { A=1.2 B=2 Z=0 (( C = A + B )) # 整数除零会触发ERR陷阱 (( D = C / Z )) } function do_float_stuff { local float_result (( float_result = 5.2 / 0 )) check_float_result "$float_result" || return 1 echo "运算结果:$float_result" } # 测试整数除零 do_stuff # 测试浮点数除零(取消注释可启用) # do_float_stuff
关键说明
ZSH_ERROR_MSG:zsh内置变量,存储最近一次错误的描述文本ERR陷阱通过$LINENO直接获取错误发生的行号check_float_result函数手动校验浮点数运算结果,主动触发错误以便陷阱捕获
测试输出示例
运行修改后的脚本,会得到类似如下输出:
jim@Tabernacle:~/ > test.zsh ************** 错误发生时间:Friday, May 24, 12:39:41 错误行号:28 错误码:1 错误原因:division by zero 当前变量值: A: 1.200000 B: 2 C: 3.200000 D: -9223372036854775808 Z: 0 **************
内容的提问来源于stack exchange,提问作者Jim Worrall
相关产品推荐
相关产品推荐

