如何使Makefile将SIGTERM信号传递给子进程?
Makefile中如何让SIGTERM信号传递给子进程?
我编写了如下Makefile规则:
sleep: trap 'echo "SIGTERM received"; exit' SIGTERM echo "falling asleep" sleep 30 echo "waking up"
期望向make进程发送SIGTERM信号时,STDOUT打印“SIGTERM received”并中断sleep进程,但实际输出如下:
$ make sleep trap 'echo "SIGTERM received"; exit' SIGTERM echo "falling asleep" falling asleep sleep 30 make: *** [Makefile:4: sleep] Terminated Terminated
解决方案
问题根源
Make默认会为规则里的每一行命令单独启动一个shell进程执行。这意味着设置trap的那行命令在自己的shell进程里执行完就退出了,后面的sleep是在全新的shell进程中运行,之前设置的信号处理完全不会作用在它身上。
方法一:将所有命令合并到同一个shell进程
用分号和反斜杠把所有命令连起来,让它们在同一个shell里执行:
sleep: trap 'echo "SIGTERM received"; exit' SIGTERM; \ echo "falling asleep"; \ sleep 30; \ echo "waking up"
方法二:使用.ONESHELL特殊目标(GNU Make 3.82+)
如果你的Make是GNU Make 3.82及以上版本,可以使用.ONESHELL目标,让整个规则的所有命令都在同一个shell进程中执行,不用手动拼接命令:
.ONESHELL: sleep: trap 'echo "SIGTERM received"; exit' SIGTERM echo "falling asleep" sleep 30 echo "waking up"
效果验证
使用以上两种方法后,向make进程发送SIGTERM信号时,会触发trap定义的处理逻辑,打印“SIGTERM received”并立即终止sleep进程,同时退出整个规则的执行。
内容的提问来源于stack exchange,提问作者Bernard Halas
相关产品推荐
相关产品推荐

