如何在 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}'
运行命令 mkdir -pv test/{a,b }
在所有平台上手动在 shell 中给出预期结果。
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 扩展在那里不起作用?
Given this very simple Makefile
:
all:
@mkdir -pv test/{a,b}
I get this output on OS X 10.6.8 and CentOS 5.5:
mkdir: created directory `test'
mkdir: created directory `test/a'
mkdir: created directory `test/b'
But on Ubuntu 11.04 I get this:
mkdir: created directory `test'
mkdir: created directory `test/{a,b}'
Running the command mkdir -pv test/{a,b}
manually in the shell on all platforms gives the expected result.
The version of GNU Make is the same on all platforms:
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]
What's different under Ubuntu and why doesn't the shell expansion work there?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题可能是 Make 生成了
/bin/sh
。它通常是系统默认 shell 的符号链接。选项 1
您可以确保它指向 bash(因为这是 bashism)。现在可能是 /bin/dash 或 /bin/sh,具体取决于您的 Ubuntu 版本。
选项 2
更简单的选项:
这将打印相同的输出两次,除非您注释掉
SHELL=
行选项 3
如果您不能/不想修改 make 文件,您可以像这样调用它所以:
要小心与子 makefile 或包含文件的交互。您可能需要查看
make -e
选项和 makeexport
关键字:http://www.gnu.org/s/hello/manual/make/Variables_002fRecursion.htmlThe problem is probably that Make spawns
/bin/sh
. It is usually a symlink to your system's default shell.Option 1
You could make sure it points to bash (as this is a bashism). Probably, it is now /bin/dash or /bin/sh, depending on your version of Ubuntu.
Option 2
Easier option:
This prints the same output twice unless you comment-out the
SHELL=
lineOption 3
If you can't/don't want to modify the make file, you can invoke it like so:
beware of interactions with sub-makefiles or includes. You might want to look at the
make -e
option and the makeexport
keyword: http://www.gnu.org/s/hello/manual/make/Variables_002fRecursion.htmlMake 有 执行此操作的函数:
扩展为
文档非常详尽。
Make has a function to do this:
gets expanded to
The docs are very thorough.
我已经很久很久没有使用 Make...
有几种方法可以指定要使用的特定 shell。旧 Make 的默认 shell 是原始的 Bourne shell。如果您想要不同的外壳,则必须自己设置。
您使用的是 Linux 和 GNU,因此我假设您使用 BASH 作为默认 shell。在您的 Make 中尝试此命令:
如果这只是打印
random =
并且不包含随机数,则您的 Make 使用 Bourne shell 作为默认 shell,而不是 BASH。 (这很奇怪,因为我认为 Linux 中没有真正的 Bourne shell...)要解决这个问题:SHELL
宏。而不是:
放置此:
这指定您要使用 BASH 而不是标准 /bin/sh Bourne shell。
如果
echo random = $RANDOM
确实打印了一个随机数,则您正在使用 BASH(或至少是 Kornshell),但 BRACE EXPANSION 可能未设置。尝试在 Makefile 中使用它:并确保
braceexpand
已打开。当您运行 Make 时它可能会关闭。It's been a long, long time since I've used Make...
There are several ways to specify a particular shell to use. The default shell for old Make was the original Bourne shell. If you wanted a different shell, you had to set it yourself.
You're using Linux and GNU, so I'll assume that you're using BASH as the default shell. Try this command in your Make:
If this simply prints
random =
and doesn't include a random number, your Make is using Bourne shell as its default shell instead of BASH. (Which is weird because I didn't think there was a real Bourne shell in Linux...) To get around this:SHELL
macro pointing to the BASH shell.Instead of:
Put this:
This specifies you want to use BASH and not the standard /bin/sh Bourne shell.
If the
echo random = $RANDOM
does print a random number, you're using BASH (or at least Kornshell), but the BRACE EXPANSION might not be set. Try using this in your Makefile:And make sure
braceexpand
is on. It could be off when you run Make.