just 配方中嵌套命令失败后为何没有停止执行?
数据小许
结论
just err 已返回非零退出码,但外层 run 配方把整个循环作为一条 shell 命令执行。默认 shell 是 sh -cu,没有启用 -e,因此循环体中的命令失败后,shell 不会自动退出。整个循环的退出状态取决于循环最终的状态;如果后续命令成功,循环可能返回 0,CI 也就会显示成功。just 的默认 shell 设置见官方 Shell 文档。
在失败时显式退出
检查每次调用的退出状态,失败时立即退出外层 shell:
run:
for path in *; do \
if [ "$path" != "err" ]; then \
just ok || exit $?; \
else \
just err || exit $?; \
fi; \
done
|| exit $? 会在对应的 just 命令失败时,用该命令的退出码结束当前 shell。这样外层 run 也会返回非零状态,CI 就能识别失败。
为什么日志显示失败却还会继续
日志中的 error: Recipe err failed ... exit code 1 表明内层 just err 确实失败了。循环作为一条复合命令传给 shell 后,shell 仍会执行循环中的后续语句。若后续命令成功,整个循环仍可能返回成功状态。
示例中的 for、if 和反斜杠续行都属于同一条 shell 命令,因此 just 会根据外层 shell 最终返回的状态判断 run 是否成功。
注意事项
示例将变量写成 "$path",避免文件名含空格或通配符时被 shell 拆分。若实际配方使用自定义 shell 或其他错误处理选项,行为可能不同。显式检查命令状态可以让停止条件更清楚。
备注:内容仅供参考。
