我有以下Makefile
FIRSTARG := $(firstword $(MAKECMDGOALS))
# use the rest as arguments
RUNARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# ...and turn them into do-nothing targets
$(eval $(RUNARGS):;@:)
test:
if [[ "$(FIRSTARG)" == "test" ]]; then \
pytest --cov --cov-report term-missing ;\
elif [[ "docker" == "$(FIRSTARG)" ]]; then \
sudo docker run merlot:latest ;\
fi;
docker : $(RUNARGS)
@echo first word: $(FIRSTARG)
.PHONY: docker build test prune
但我收到错误
if [[ "test" == "test" ]]; then \
pytest --cov --cov-report term-missing ;\
elif [[ "docker" == "test" ]]; then \
sudo docker run merlot:latest ;\
fi;
/bin/sh: 1: [[: not found
/bin/sh: 3: [[: not found
我也尝试过使用
ifeq ("test","@(FIRSTARG)")
,它引发了不同的错误。我已经对此进行了相当多的搜索,但似乎找不到比较目标内部字符串的正确方法。您能帮我找到在 make 目标中进行字符串比较的正确方法吗?
谢谢!
所有 make 程序都会调用
/bin/sh
,这是一个符合 shell 脚本 POSIX 规范的 shell。 POSIX 标准没有定义运算符 [[
,所以你不能使用它。
最好的办法是使用 POSIX 标准脚本,因此只需使用
[
而不是 [[
,并且仅使用 =
而不是 ==
。
错误消息中的关键线索是
/bin/sh: 1: [[: not found
也就是说,它是
/bin/sh
抱怨命令 [[
不存在。这是真的,因为 sh
中没有这样的命令。这是 bash
中的有效语法,它通常是功能更强大的 shell,但 Makefile 默认情况下使用 /bin/sh
执行其操作。
可以更改 Make 使用的 shell,但通常最好顺其自然并在操作中使用仅限 sh 的语法。因此我怀疑,如果你改变你的行为
if test "$(FIRSTARG)" = "test"; ...
(有关详细信息,请参阅
man test
)那么您所拥有的可能会起作用。
旁注:
[[
不是 bash
中的命令 – 它是内置语法。 [
和sh
中都有一个命令bash
,它只是test
的同义词。