【结论】使用重定向来代替 tee,这个方案我采纳;不过 build.log 建议直接放在 tmp/ 下,让它跟构建产物一起被 .gitignore 和每轮的清理逻辑一并处理,不用单独加一条规则。
既然编译命令统一收进 Makefile,sh 层那层 || { ...; exit 1; } 就可以省掉了:make 退出码本身就是可靠的,make build 失败会返回非 0,&& 后面自然不执行。所以写成 sh -c 'make -s build && exec ./tmp/app' 就够了,-s 顺手把 make 自己的 “Entering directory” 压掉,日志更干净。唯一要盯的是同步关系变了:bin 必须跟 Makefile 里 -o 的目标一致,而不是跟 air 的 cmd 一致,改名时只改一处但改的是 Makefile 那处。
旧二进制那个坑,除了保留 stop_on_error = true 之外,还有个更彻底的做法:让产物每轮换名,再原子替换,go build -o ./tmp/app.new ./cmd/app && mv ./tmp/app.new ./tmp/app,就不存在 air 在编译中途拉起、读到半个可执行文件的窗口。普通项目 rm -rf tmp 加 stop_on_error 基本够用,但容器里那段 2 秒 kill_delay 期间被拉起的概率不算低,值得加。
--start-service 那个选项我不是很有把握,名字和它到底怎么处理信号转发、子进程退出码怎么上报,我不敢替你打包票,建议 reflex --help | grep -i service 确认一下再决定要不要用。我个人的倾向还是放在 sh 层统一处理:换工具、上 systemd、进容器,行为都是同一套,不用为每个工具单独记忆一份参数。
正式会员
认证极客









