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

发布于 2024-11-20 00:27:31 字数 944 浏览 2 评论 0原文

给定这个非常简单的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一世旳自豪 2024-11-27 00:27:31

问题可能是 Make 生成了 /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

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

The 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:

SHELL=/bin/bash

all:
    @echo a{3,4}
    @bash -c 'echo a{3,4}'

This prints the same output twice unless you comment-out the SHELL= line

Option 3

If you can't/don't want to modify the make file, you can invoke it like so:

make SHELL=/bin/bash

beware of interactions with sub-makefiles or includes. You might want to look at the make -e option and the make export keyword: http://www.gnu.org/s/hello/manual/make/Variables_002fRecursion.html

后来的我们 2024-11-27 00:27:31

Make 有 执行此操作的函数

    @mkdir -pv $(addprefix test/,a b)

扩展为

    @mkdir -pv test/a test/b

文档非常详尽。

Make has a function to do this:

    @mkdir -pv $(addprefix test/,a b)

gets expanded to

    @mkdir -pv test/a test/b

The docs are very thorough.

雨的味道风的声音 2024-11-27 00:27:31

我已经很久很久没有使用 Make...

有几种方法可以指定要使用的特定 shell。旧 Make 的默认 shell 是原始的 Bourne 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 时它可能会关闭。

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:

echo "random = $RANDOM"

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:

  • You can add in a SHELL macro pointing to the BASH shell.
  • You can include the shell in your command.

Instead of:

@mkdir -pv test/{a,b}

Put this:

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

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:

set -o

And make sure braceexpand is on. It could be off when you run Make.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文