问题描述
我有一个复杂的脚本c.sh
,用于测试机器make某些环境正在运行。应该使用bash
运行它。它会打印一些有用的信息,以供stdout
和stderr
使用。如果满足某些特殊条件,则c.sh
存在,退出代码为1,否则为0。如果出现问题,则可能会出现其他退出代码。根据退出代码,我要执行不同的配方。
all:
# test using c.sh
everything-OK: # prerequisites
# *recurse* on this if c.sh exits with zero
# e.g. "$(MAKE) everything-OK" in all if ...
something-went-wrong: # prerequisites
# *recurse* on this if c.sh exists with anything else
我找到了this有用的答案,但并没有太大帮助。由于我似乎无法使递归工作或取决于退出代码的if开关。刚开始使用$(.SHELLSTATUS)
看起来很有希望,但是该解决方案不会立即从脚本中重定向stdout
。
替代解决方案可能看起来像这样:
EVERYTHING_OK = 0 # 0: false,1: true
all:
# test using c.sh
# set EVERYTHING_OK depending on exit code
$(MAKE) second-stage
ifeq (1,EVERYTHING_OK)
second-stage: # prerequisites
# ...
else
second-stage: # prerequisites
# ...
endif
(我喜欢这个,因为我可以将if条件放在宏中)
解决方法
如果您只对脚本的退出状态感兴趣,则最简单的方法可能是将其捕获到make变量中,并在make条件或目标名称中使用它。目标名称示例:
C_EXIT_STATUS := $(shell ./c.sh &> /dev/null; echo $$?)
.PHONY: all everithing-%
all: everything-$(C_EXIT_STATUS)
everything-0:
@echo "all right"
everything-%:
@echo "not all right ($*)"
然后,如果./c.sh
以状态0退出:
$ make all
all right
如果退出状态为7:
$ make all
not all right (7)
带有条件的示例:
C_EXIT_STATUS := $(shell ./c.sh &> /dev/null; echo $$?)
.PHONY: all
ifeq ($(C_EXIT_STATUS),0)
all:
@echo "all right"
else
all:
@echo "not all right ($(C_EXIT_STATUS))"
endif
最后但并非最不重要的一点,正如您自己建议的那样,递归make也是一种选择:
.PHONY: all
ifeq ($(C_EXIT_STATUS),)
all:
s=0; ./c.sh &> /dev/null || s=$$?; \
$(MAKE) C_EXIT_STATUS=$$s
else ifeq ($(C_EXIT_STATUS),0)
all:
@echo "all right"
else
all:
@echo "not all right ($(C_EXIT_STATUS))"
endif