set -Eeuo pipefail trap 'echo "failed at line $LINENO" >&2' ERR
脚本里注册了 trap 'echo failed' ERR 想统一处理失败,实际跑下来命令返回 1,trap 一次都没执行,脚本继续往下走。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。
追下去是这么回事:ERR trap 只对简单命令生效,命令放在 if 条件、&& 链或者函数调用里时,shell 认为失败已被处理,不再触发。函数内部也没有继承 trap,除非开了 errtrace。
「trap ERR 不生效」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。权限不要一口气开到最大,先加到够用再往上试,范围小才好收。
把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。
处理上按这个顺序:确认 trap 写在脚本顶层 不在函数里;set -E 让 ERR trap 继承到函数和子 shell;避免在 if 或 || 里吞掉关键命令的返回值;故意让中间命令失败一次 确认 trap 输出。
确认没问题再收工,中间命令失败时立刻打印行号并退出,不再继续执行后面的步骤。
