为了说明这个问题,我创建了一个makefile,它先定义一个汽车列表,然后为每辆汽车创建一个颜色列表:
CARS = Ford Ferrari Mercedes Toyota
Ford_COLOURS = black blue red white
Ferrari_COLOURS = red
Mercedes_COLOURS = black blue silver
Toyota_COLOURS = blue red white
然后,我想在我的一个制作目标中遍历每辆车的所有颜色:
.PHONY: list
list:
for car in ${CARS} ; do \
car_colours=$${car}_COLOURS ; \
echo $${car_colours} = "$${!car_colours}" ; \
eval colours="$${!car_colours}" ; \
for colour in $${colours} ; do \
echo $${colour} ; \
done ; \
done
正如您所看到的,我尝试综合this question about generating dynamic variable names in bash中的想法和this question about how to evaluate (expand) dynamic names in bash的一些答案。
不幸的是我得到以下输出:
Ford_COLOURS =
Ferrari_COLOURS =
Mercedes_COLOURS =
Toyota_COLOURS =
虽然我希望得到这样的东西:
Ford_COLOURS = black blue red white
black
blue
red
white
Ferrari_COLOURS = red
red
Mercedes_COLOURS = black blue silver
black
blue
silver
Toyota_COLOURS = blue red white
blue
red
white
我该如何解决?
答案 0 :(得分:2)
在my comment到Jonathan's answer之后,我找到了一种方法,涉及从执行内部make
循环的片段中启动另一个for
进程:
.PHONY: list
list:
for car in ${CARS} ; do \
car_colours_var=$${car}_COLOURS ; \
${MAKE} CAR_COLOURS_VAR=$${car_colours_var} single_car ; \
done
.PHONY: single_car
single_car:
for colour in ${${CAR_COLOURS_VAR}} ; do \
echo $${colour} ; \
done
密钥是中间CAR_COLOURS_VAR
,它作为参数传递给子make
进程,随后可以通过${${CAR_COLOURS_VAR}}
语法扩展该进程。
答案 1 :(得分:1)
问题是shell不知道'make_COLOURS'的列表。您可以使用:
CARS = Ford Ferrari Mercedes Toyota
Ford_COLOURS = black blue red white
Ferrari_COLOURS = red
Mercedes_COLOURS = black blue silver
Toyota_COLOURS = blue red white
.PHONY: list
list:
Ford_COLOURS="${Ford_COLOURS}"; \
Ferrari_COLOURS="${Ferrari_COLOURS}"; \
Mercedes_COLOURS="${Mercedes_COLOURS}"; \
Toyota_COLOURS="${Toyota_COLOURS}"; \
for car in ${CARS} ; do \
car_colours=$${car}_COLOURS ; \
echo $${car_colours} = "$${!car_colours}" ; \
colours="$${!car_colours}" ; \
for colour in $${colours} ; do \
echo $${colour} ; \
done ; \
done
请注意,原始eval
中的eval colours="$${!car_colours}"
已丢失eval
。如果存在,则会出现/bin/sh: blue: command not found
之类的错误,因为eval
有colours=black blue red white
并尝试执行blue
,并将环境变量colours
设置为{{} 1}}。