如何在Ubuntu下处理GNU Make中的shell扩展?

鉴于这个非常简单的Makefile

 all: @mkdir -pv test/{a,b} 

我在OS X 10.6.8和CentOS 5.5上得到这个输出:

 mkdir: created directory `test' mkdir: created directory `test/a' mkdir: created directory `test/b' 

但在Ubuntu 11.04我得到这个:

 mkdir: created directory `test' mkdir: created directory `test/{a,b}' 

在所有平台上的shell中手动运行命令mkdir -pv test/{a,b}会给出预期的结果。

GNU Make的版本在所有平台上都是一样的:

 GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program is built for [PLATFORM] 

在Ubuntu下有什么不同,为什么在这里没有shell扩展?

问题可能是Make spawns /bin/sh 。 它通常是系统默认shell的符号链接。

选项1

你可以确定它指向bash(因为这是一个bashism)。 现在可能是/ bin / dash或/ bin / sh,这取决于你的Ubuntu版本。

选项2

更简单的选项:

 SHELL=/bin/bash all: @echo a{3,4} @bash -c 'echo a{3,4}' 

这将打印相同的输出两次,除非您注释掉SHELL=

选项3

如果你不能/不想修改make文件,你可以这样调用它:

 make SHELL=/bin/bash 

注意与子文件或包含的交互。 您可能需要查看make -e选项和make export关键字: http : //www.gnu.org/s/hello/manual/make/Variables_002fRecursion.html

自从我使用Make以来,已经有很长一段时间了。

有几种方法可以指定一个特定的shell来使用。 旧Make的默认shell是原始的Bourne shell。 如果你想要一个不同的shell,你必须自己设置它。

你正在使用Linux和GNU,所以我假设你使用BASH作为默认的shell。 在你的Make中试试这个命令:

 echo "random = $RANDOM" 

如果这只是打印random =而不包含一个随机数,那么Make就是使用Bourne shell作为它的默认shell而不是BASH。 (这很奇怪,因为我不认为在Linux中有一个真正的Bourne shell …)为了解决这个问题:

  • 您可以添加一个指向BASH shell的SHELL宏。
  • 你可以在你的命令中包含shell。

代替:

 @mkdir -pv test/{a,b} 

把这个:

 /bin/bash -c @mkdir -pv test/{a,b} 

这指定你想要使用BASH而不是标准的/ bin / sh Bourne shell。

如果echo random = $RANDOM确实打印了一个随机数,那么您使用的是BASH(或至少是Kornshell),但BRACE EXPANSION可能不会被设置。 尝试在你的Makefile中使用这个:

 set -o 

并确保braceexpand打开。 运行Make时可能会关闭。