Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
236 views
in Technique[技术] by (71.8m points)

shell - Is it possible to compare a variable with multiple values in if statement of a make target?

I am trying to run a make target where a particular value is passed on CLI, but this value should be compared with 2 or more possible values, like the value being passed on cli should be equal to any one from the pre existing list, so that the condition becomes true and if block gets executed!

.PHONY:plan-infra
plan-infra: configure  ## Plan Infra
    @if [ "${infra_module_path}" = "emr" or "gmr" ]; then
        echo "test";
    fi


$ make plan-infra -e infra_module_path=emr

So if the variable "infra_module_path" is either "emr" or "gmr" the if block should get executed!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The filter GNU make function is your friend:

.PHONY:plan-infra

MATCH := $(filter emr gmr,$(infra_module_path))

plan-infra: configure  ## Plan Infra
    @if [ -n "$(MATCH)" ]; then
        echo "test";
    fi

But note that this will also match if you pass values containing several space-separated tokens with at least one matching, e.g.,

make plan-infra -e infra_module_path="emr foo bar"

As noted by MadScientist, filter-out is a bit better because it returns the empty string when the string contains only the filtered tokens; it is thus more accurate:

.PHONY:plan-infra

MATCH := $(filter-out emr gmr,$(infra_module_path))

plan-infra: configure  ## Plan Infra
    @if [ -z "$(MATCH)" ]; then
        echo "test";
    fi

But it is still not 100% accurate:

make plan-infra -e infra_module_path="emr qmr"

still matches. If your really need exact match, while it is doable with make functions (at least in your case), as noted by Charles Duffy and MadScientist, it would be better to use shell constructs. Just in case you absolutely need exact match using make functions:

.PHONY:plan-infra

ifeq ($(words $(infra_module_path)),1)
MATCH := $(filter-out emr gmr,$(infra_module_path))
else
MATCH := no
endif

plan-infra: configure  ## Plan Infra
    @if [ -z "$(MATCH)" ]; then
        echo "test";
    fi

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...