在Makefile中迭代bash关联数组

布莱恩
$ bash -version
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)

考虑以下shell脚本:

#!/bin/bash

declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )

for key in "${!PROVS[@]}" ; do \
  touch "foo_${key}_${PROVS[${key}]}" ; \
done

我正在尝试在Makefile中做同样的事情:

SHELL := /bin/bash
.PHONY: foo
foo:
  declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )

  for key in "$${!PROVS[@]}" ; do \
    touch "foo_$${key}_$${PROVS[$${key}]}" ; \
  done

我并不真的想要touch的文件; 我这样做是因为我不能@echo-因为我处于循环中,所以@不会被视为位于行的开头。或这似乎正在发生。

无论如何,关键是循环似乎根本没有运行,因此touch/echo业务。上面的shell脚本的内容恰好是回显make到终端的内容。我添加了shebang并将其作为健全性检查运行-就像魅力一样。

使用常规数组可以正常工作:

for prov in NL PE NS NB QC ON MB SK AB BC YK NT NU ; do \

但是,我也需要这些代码(10、11等)。

有人对此有见识吗?

尽管我不需要它,但我也想知道如何(或者是否有可能)在文件顶部分配PROVS变量,同时也使用“ declare -A”。

编辑:我不知何故弄乱了Makefile示例,以便它只是一些内联shell命令,而不再是配方。我已添加回“ foo:”目标以进行澄清。

三元组

如果您的代码摘录正确地代表了代码,则表明您正在直接在Makefile中键入Bash命令,并期望Make使用Bash执行它们。那不是它的工作原理。Makefile的语法完全不同。配方中,您可以键入Bash命令。配方中的每一行都将在单独的子Shell中执行。因此,您至少需要进行两项更改:

  • 您的shell命令必须位于目标中。
  • declare需要在同一个外壳作为循环运行; 否则,您将declare处于一个Bash实例中,然后退出该实例,然后在另一个实例中运行循环,该实例对现在丢失的消息一无所知declare

这是通过这些更改对Makefile进行的简单重构。

SHELL=/bin/bash   # This is the standard compliant method

.PHONY: all
all:
    declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 \
        ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 \
        ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )\
    ; for key in "$${!PROVS[@]}" ; do \
        touch "foo_$${key}_$${PROVS[$${key}]}" ; \
    done

演示:http//ideone.com/t94AOB

@静默运行命令约定适用于整个命令行。因此,您可以将其放在declare上面,在这种情况下,它将在整个命令行提交给Bash之前被剥离。在其他任何地方,它都不会被剥离或理解,并且显然会在被调用的shell中引起Bash语法错误。

@无论如何,对规则的痴迷是一种反模式。make -s如果您不想看到输出,请运行;关闭make将只会增加调试规则的难度。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章