【问题标题】:bash builtin commands in makefilemakefile 中的 bash 内置命令
【发布时间】:2015-10-21 14:17:19
【问题描述】:

按照规则清理makefile中的所有二进制文件不起作用。

SHELL:=bash
PHONY: clean
clean:
    for file in {"greedy","mario","pset1_mario","credit","hello"}; do \
        [[ -e "${file}" ]] && rm ${file}; \
    done

它给出以下错误信息。

recipe for target 'clean' failed make: *** [clean] Error 1

如果我使用 make 文件中的相同命令调用另一个 shell 脚本,它会起作用。

clean:
    bash ./cleanup.sh

有没有办法可以将这些命令放入 makefile 本身?

【问题讨论】:

  • 变量上需要两个美元符号:$${file} 在这种情况下。

标签: shell makefile


【解决方案1】:

因为Error 1 不是你想的那样。

在 makefile 中使用SHELL:=/bin/bash -x,你会发现你运行的不是你期望运行的。

具体来说,您忘记将配方中的 $ 从 make 中转义,因此您不是在 -e 测试中测试该列表中的每个名称,而是测试空字符串 ([ -e "" ])。然后每次循环都会失败。

last 时间在循环失败时 for 循环结束,并且由于循环中的最后一个命令以失败返回退出,整个循环以失败返回结束,因此 make 看到脚本以失败结尾并报告。

你想要这个:

SHELL:=bash
.PHONY: clean
clean:
        for file in {"greedy","mario","pset1_mario","credit","hello"}; do \
            [[ ! -e "$${file}" ]] || rm $${file}; \
        done

注意 shell 变量上的双 $$ 并注意测试和条件的反转。 make recipe 行需要返回成功,除非您希望它们终止 make。

还要注意.PHONY 那里。 PHONY 只是一个普通的目标。

更新:

可能还值得指出的是,这个 sn-p 没有从大括号扩展或特定于 bash 的 [[ 测试中获得任何好处,并且可以很容易地以与 sh 兼容的方式重写:

clean:
        for file in greedy mario pset1_mario credit hello; do \
            [ ! -e "$${file}" ] || rm $${file}; \
        done

【讨论】:

  • ...而整个概念“如果存在则删除,否则默默忽略”正是rm -f 所做的事情
猜你喜欢
  • 2012-04-24
  • 2017-01-21
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
相关资源
最近更新 更多