为什么不通过make(w / SHELL:= / bin / bash)执行支持!(...)模式?

时间:2017-02-12 15:25:12

标签: linux bash shell makefile

我在Makefile中运行一行代码时遇到问题,该代码行在/bin/bash中运行良好。我知道Make在/bin/sh中运行所以我solved that problem with this guide声明要让我希望它在Bash中运行。然而,即使我在Bash中运行Make,我仍然无法让这条线工作,即使它很难在Bash中工作也很好。

为什么Bash在Makefile中运行rm -f !(2).txt时抛出错误,但在shell中执行时却没有?

  

编辑:我试图删除除了其中一个文件之外的具有特定文件扩展名的所有文件。我的bash终端中的命令rm -f !(2).txt does just that,但不是Make。

     

编辑:正常运行rm -f !(2).txt""在带有Bash的终端中(终端在发出命令bash时返回echo "$0")它运行正常,但是我运行/bin/bash -c 'rm -f !(2).txt'我得到了与Makefile中相同的错误。

生成文件

all: clean

clean: SHELL:=/bin/bash
clean:
    rm -f !(2).txt

在Bash中运行命令

 $ ls
1.txt  2.txt  3.txt  4.txt  Makefile    # Directory has all text files
 $ rm -f !(2).txt                       # Remove all text files but 2.txt
 $ ls
2.txt  Makefile                         # Only 2.txt is not removed

在Bash到Makefile中运行命令

 $ ls                                   # Directory has all text files
1.txt  2.txt  3.txt  4.txt  Makefile
 $ make clean                           # Running make 
rm -f !(2).txt
/bin/bash: -c: line 0: syntax error near unexpected token `('
/bin/bash: -c: line 0: `rm -f !(2).txt'
make: *** [clean] Error 1

2 个答案:

答案 0 :(得分:2)

您需要启用extglob shell选项才能使其正常工作。在GNU make中,可以通过

来实现
SHELL := /bin/bash
.SHELLFLAGS := -O extglob -c

按问题作者编辑

上面两行代码的示例对我不起作用,但作为this fellow found out,似乎有不同的解决方案,具体取决于版本。

  

嗯。出于某种原因,.SHELLFLAGS对我没有用,但直接将标记放在SHELL=/bin/bash -O extglob -c中。 [...] - 蒂莫西·琼斯

示例@choroba使用Make 4.0中的作品,但由于我有Make 3.81,因此对我不起作用。但是,这是我的解决方案:

all: clean

clean: SHELL=/bin/bash -O extglob -c
clean:
    rm -f !(2).txt

答案 1 :(得分:0)

让我们不知道"!(2).txt"意味着,如果你真的必须使用这个构造,那么使用$(shell)函数:

%(shell rm -f !(2).txt)

就个人而言,我会更改您的文件命名方案或在make变量中构建您要删除的文件名。