如何在单个Makefile规则中启动并终止后台进程
问题分析与解决
你的问题核心是Makefile的每一行命令都会启动独立的shell进程,所以@$(MAKE) run-server&和后面的export SERVER_PID=$! ...不在同一个shell环境里,自然拿不到后台进程的PID,导致SERVER_PID为空。另外原方案还存在进程泄漏风险:如果cmd-that-uses-server执行失败,后续的kill不会触发,后台服务器会一直运行。
修正后的Makefile代码
run-server: ## Run the server in the foreground. run server run-kill-server: ## Run the server while using it. @$(MAKE) run-server & \ SERVER_PID=$$!; \ trap "kill $${SERVER_PID} 2>/dev/null" EXIT; \ cmd-that-uses-server
关键说明
- 用反斜杠
\把所有命令连为逻辑上的同一行,强制Make在单个shell进程里执行所有操作,这样$$!就能正确获取后台make run-server的PID(Make中需要写$$!,单个$会被Make提前解析)。 - 使用
trap捕获EXIT信号,不管cmd-that-uses-server执行成功还是失败,都会触发kill操作,彻底避免进程泄漏。 2>/dev/null用来忽略kill可能产生的“进程不存在”错误(比如服务器自己提前退出的情况)。
内容的提问来源于stack exchange,提问作者Intrastellar Explorer
相关产品推荐
相关产品推荐

