最有效方式是用 set -e 和 trap 'log "error at line $lineno"' err 主动捕获错误行号,配合 exit trap 做兜底日志与清理,辅以 caller、bash -x 等手段增强定位精度。

在 Linux 运维脚本中,捕获并记录崩溃(即非预期退出)时的**具体行号**,关键不是等它“崩溃”后再抓,而是用 set -e + trap ERR 主动拦截错误,并结合 $LINENO 获取位置。
用 trap 'log "Error at line $LINENO"' ERR 捕获任意位置错误
这是最直接有效的方式。只要脚本中某条命令返回非零退出码(且未被显式忽略),ERR 信号就会触发,$LINENO 自动指向出错命令所在的行号。
- 必须启用错误传播:
set -e或在关键命令后加|| exit $? -
trap要放在脚本开头,确保覆盖全部逻辑范围 - 真实退出码可通过
$?获取,避免被后续命令覆盖
示例:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
trap 'log "Error at line $LINENO"; exit $?' ERR
set -e
cp /missing/file /dest/ # 这里出错,会记录 "Error at line 4"
配合 EXIT trap 确保日志落盘和资源清理
ERR 只在命令失败时触发,但脚本可能因 kill -9、系统中断等无法捕获。用 trap ... EXIT 做兜底,同时记录最终状态。
- 可检查
$?是否非零,判断是否属于异常退出 - 适合写入结束标记、关闭临时文件、发送告警等
- 注意:EXIT 在所有退出路径(包括正常 exit)都会执行
示例:
trap 'if [ $? -ne 0 ]; then log "Script exited abnormally with code $?"; fi' EXIT补充技巧:让错误信息更完整
单靠行号有时不够,比如变量展开失败、语法错误或子 shell 报错,$LINENO 可能不准。可叠加以下手段:
- 启用调试模式临时定位:
bash -x script.sh查看每步执行及变量值 - 记录函数调用栈:
echo "Call stack: $(caller)"放在 trap 里(需 bash 4.1+) - 对关键块加人工标记:
log "Starting backup at $(date)",缩小排查范围










