Bash在Makefile中扩展了globbing


15

我想对不以特定前缀开头(例如exclude_)的特定文件夹中的所有文件执行操作。我有一个bash for循环,带有一个扩展的glob,看起来像这样:

for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done

在命令行上,这可以正常工作:

 $ for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done
 foo/bar/apple
 foo/bar/pear
 foo/bar/banana

但是,当我在makefile中使用它时:

target:
    for FILE in foo/bar/!(exclude_*) ; do echo $$FILE ; done

我收到以下错误:

$ make
for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `for FILE in foo/bar/!(exclude_*) ; do echo $FILE ; done'

我错过了一些必要的转义吗?

Answers:


7
  1. 您需要设置extglob
  2. 您需要告诉make使用bash,而不是sh。

生成文件:

SHELL=/bin/bash
.SHELLFLAGS="-O extglob -c"
 ...

2
嗯 出于某种原因,.SHELLFLAGS它对我不起作用,但是直接将标志放进去是可行的SHELL=/bin/bash -O extglob -c。有什么想法吗?
蒂莫西·琼斯

1
也许您没有使用GNU make。或者,也许不需要引号。
伊格纳西奥·巴斯克斯

GNU Make 3.81和GNU bash版本4.1.2。试过也没有引号。奇怪的。
蒂莫西·琼斯

无论如何,一旦我将它们全部放在一条线上,您的答案就为我解决了。谢谢!
蒂莫西·琼斯

1
.SHELLFLAGS变量已添加到GNU make 3.82中。您可以通过NEWS文件检查哪些版本中添加了哪些功能:git.savannah.gnu.org/cgit/make.git/tree/NEWS
MadScientist

11

用Make而不是Bash hack来解决这个问题会更惯用,更便于移植。如果有人没有安装Bash怎么办?

无论如何,这是在Make中执行此操作的正确方法

FOOFILES = $(filter-out foo/bar/exclude_%,$(wildcard foo/bar/*))

target:
    for FILE in ${FOOFILES}; do echo $$FILE ; done

2

这是一种更简单的方法:

SHELL:=/bin/bash -O globstar

这将启用globstar shell选项(也适用于BSD / OS X)。


0

将此添加到Makefile的顶部:

SHELL := bash -O extglob

1
不起作用 上面的版本是正确的。
Desik '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.