Makefile目标中字符串比较报错,寻求正确实现方法
解决Makefile中字符串比较的错误问题
错误原因
报错/bin/sh: 1: [[: not found是因为[[是Bash的扩展语法,而Make默认使用POSIX标准的/bin/sh(多数Linux系统中为Dash,不支持[[语法)。
解决方案
方案1:指定Make使用Bash执行命令
在Makefile最顶部添加一行,强制Make用Bash解析shell命令,这样就能正常使用[[语法:
SHELL := /bin/bash FIRSTARG := $(firstword $(MAKECMDGOALS)) RUNARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) $(eval $(RUNARGS):;@:) test: if [[ "$(FIRSTARG)" == "test" ]]; then \ pytest --cov --cov-report term-missing ;\ elif [[ "$(FIRSTARG)" == "docker" ]]; then \ sudo docker run merlot:latest ;\ fi; docker : $(RUNARGS) @echo first word: $(FIRSTARG) .PHONY: docker build test prune
方案2:使用POSIX兼容的[命令
把shell中的[[替换为POSIX标准的[,同时将==改为=(POSIX sh仅支持=做字符串比较),注意[和]前后必须加空格:
FIRSTARG := $(firstword $(MAKECMDGOALS)) RUNARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) $(eval $(RUNARGS):;@:) test: if [ "$(FIRSTARG)" = "test" ]; then \ pytest --cov --cov-report term-missing ;\ elif [ "$(FIRSTARG)" = "docker" ]; then \ sudo docker run merlot:latest ;\ fi; docker : $(RUNARGS) @echo first word: $(FIRSTARG) .PHONY: docker build test prune
方案3:用Make原生条件判断(更符合Makefile设计)
你之前尝试的ifeq写法有误,正确的Make条件判断语法是ifeq ($(变量), 值),且要写在shell命令块之外。另外你的逻辑其实可以拆分到不同目标中,结构更清晰:
FIRSTARG := $(firstword $(MAKECMDGOALS)) RUNARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) $(eval $(RUNARGS):;@:) test: pytest --cov --cov-report term-missing docker : $(RUNARGS) @echo first word: $(FIRSTARG) sudo docker run merlot:latest .PHONY: docker build test prune
如果一定要在单个目标中用Make条件判断,写法如下:
test: ifeq ($(FIRSTARG),test) pytest --cov --cov-report term-missing endif ifeq ($(FIRSTARG),docker) sudo docker run merlot:latest endif
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

