You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Makefile Recipe中的Bash循环在命令失败时立即终止

解决Makefile中jsonnet命令失败时立即终止流程的问题

修改后的Makefile代码(GNU环境)

run_pipelines:
	@[ "${filter}" ] || filter="."; \
	filter=$$(echo "$$filter" | sed -e 's/\./.*/g') && echo $${filter}"<3" && \
	echo "\033[1;34m#######Running Pipelines for $${filter}#######\033[0m" && \
	find v2/services -type f -regex ".*$${filter}.*.jsonnet" -print0 | \
	xargs -r -0 --exit-on-error -I {} bash -e -c 'echo -e "\033[1;32mjsonnet {} \033[0m"; jsonnet {}'
.PHONY: run_pipelines

关键修改点说明

  1. 修复filter变量赋值的隐藏bug
    原来的( filter="."; )是在子shell中执行,赋值的变量无法传递到后续命令,导致未指定filter时,后续sed处理会得到空值,find的正则匹配完全失效。改成filter=".";让变量在当前shell生效,确保逻辑正确。

  2. 让bash脚本遇错即停
    使用bash -e选项,只要脚本内的任何命令返回非零状态,bash就会立即退出,替代原来手动写的|| exit $?,逻辑更简洁可靠。

  3. 强制xargs第一个失败就停止
    添加--exit-on-error选项(GNU xargs支持),告诉xargs只要某个被执行的命令失败,就立刻停止处理剩余的文件,避免继续执行后续jsonnet命令。

通用兼容版(适配BSD等非GNU环境)

如果你的环境不支持--exit-on-error,可以改用for循环替代xargs,利用make本身的特性——只要recipe中某条命令失败就终止:

run_pipelines:
	@[ "${filter}" ] || filter="."; \
	filter=$$(echo "$$filter" | sed -e 's/\./.*/g') && echo $${filter}"<3" && \
	echo "\033[1;34m#######Running Pipelines for $${filter}#######\033[0m" && \
	for file in $$(find v2/services -type f -regex ".*$${filter}.*.jsonnet"); do \
		echo -e "\033[1;32mjsonnet $$file \033[0m"; \
		jsonnet $$file; \
	done
.PHONY: run_pipelines

这个版本中,只要某个jsonnet命令失败,for循环就会终止,整个recipe返回失败状态,make也会停止运行。

内容的提问来源于stack exchange,提问作者anwerj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:31:23