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

42fyovps  于 2022-11-22  发布在  Shell
关注(0)|答案(3)|浏览(133)

给定这个非常简单的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扩展在那里不起作用?

nfs0ujit

nfs0ujit1#

问题可能是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或include的交互。您可能需要查看make -e选项和make export关键字:http://www.gnu.org/s/hello/manual/make/Variables_002fRecursion.html

cl25kdpy

cl25kdpy2#

Make有一个功能可以做到这一点:

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

扩展到

@mkdir -pv test/a test/b

The docs非常彻底。

k2arahey

k2arahey3#

我已经很久很久没有使用Make了...
有几种方法可以指定要使用的特定shell。旧Make的默认shell是原始的Bourne shell。如果你想要一个不同的shell,你必须自己设置它。
您使用的是Linux和GNU,所以我假设您使用的是BASH作为默认shell。

echo "random = $RANDOM"

如果这只是打印random =并且不包含随机数,那么您的Make使用的是Bourne shell而不是BASH作为默认shell。(这很奇怪,因为我认为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可能没有设置。

set -o

并确保braceexpand处于打开状态。运行Make时,它可能处于关闭状态。

相关问题