如何执行Makefile的other目标时避免加载backup目标的连接变量?
解决方案
核心问题是Makefile的全局变量和顶层条件判断会在解析阶段就执行,不管你最终要执行哪个目标。要让这些仅和backup相关的逻辑只在执行backup时触发,可采用以下几种实用方法:
方法1:利用MAKECMDGOALS条件判断
MAKECMDGOALS变量会保存你在命令行指定的目标列表,通过它判断是否要加载backup相关的变量和逻辑:
.PHONY: backup other # 仅当目标包含backup时才初始化相关变量并执行检查 ifneq (,$(filter backup,$(MAKECMDGOALS))) REMOTE_HOST := server1 DOMAIN_NAME := vm1 VM_IS_RUNNING := $(shell ssh $(REMOTE_HOST) virsh domstate "$(DOMAIN_NAME)") ifneq ($(.SHELLSTATUS), 0) $(error SSH command failed with status $(.SHELLSTATUS)) endif endif ################################################################################ backup: ifeq ($(VM_IS_RUNNING),running) @echo "VM $(DOMAIN_NAME) is running." @exit 0 else @echo "VM $(DOMAIN_NAME) is NOT running." @exit 0 endif ################################################################################ other: @echo "hello"
执行make other时,filter backup,$(MAKECMDGOALS)返回空,不会进入条件块,也就不会执行SSH命令和变量初始化。
方法2:将逻辑移到目标的shell脚本中
把backup的检查逻辑直接写到目标命令里,避免全局解析阶段执行:
.PHONY: backup other REMOTE_HOST := server1 DOMAIN_NAME := vm1 ################################################################################ backup: @VM_STATE=$$(ssh $(REMOTE_HOST) virsh domstate "$(DOMAIN_NAME)"); \ if [ $$? -ne 0 ]; then \ echo "SSH command failed with status $$?"; \ exit 1; \ fi; \ if [ "$$VM_STATE" = "running" ]; then \ echo "VM $(DOMAIN_NAME) is running."; \ else \ echo "VM $(DOMAIN_NAME) is NOT running."; \ fi; \ exit 0 ################################################################################ other: @echo "hello"
所有检查逻辑都被限制在backup目标的shell命令中,执行make other时完全不会触发SSH相关操作。
方法3:使用依赖目标封装逻辑
创建一个仅用于backup的依赖目标,把变量初始化和检查放到这个目标的命令里:
.PHONY: backup other check_vm_state REMOTE_HOST := server1 DOMAIN_NAME := vm1 # 仅当backup被执行时才会触发这个依赖 check_vm_state: @VM_STATE=$$(ssh $(REMOTE_HOST) virsh domstate "$(DOMAIN_NAME)"); \ if [ $$? -ne 0 ]; then \ echo "SSH command failed with status $$?"; \ exit 1; \ fi; \ echo "$$VM_STATE" > .vm_state.tmp backup: check_vm_state @VM_STATE=$$(cat .vm_state.tmp); \ rm .vm_state.tmp; \ if [ "$$VM_STATE" = "running" ]; then \ echo "VM $(DOMAIN_NAME) is running."; \ else \ echo "VM $(DOMAIN_NAME) is NOT running."; \ fi; \ exit 0 other: @echo "hello"
通过临时文件传递VM状态,确保只有执行backup时才会运行SSH命令。
内容的提问来源于stack exchange,提问作者Martin Vegter
相关产品推荐
相关产品推荐

