如何在 Makefile 目标中使用 Bash 语法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/589276/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 17:58:31  来源:igfitidea点击:

How can I use Bash syntax in Makefile targets?

bashshellmakefile

提问by Frank

I often find Bashsyntax very helpful, e.g. process substitution like in diff <(sort file1) <(sort file2).

我经常发现Bash语法非常有用,例如像 in 的进程替换diff <(sort file1) <(sort file2)

Is it possible to use such Bash commands in a Makefile? I'm thinking of something like this:

是否可以在 Makefile 中使用此类 Bash 命令?我在想这样的事情:

file-differences:
    diff <(sort file1) <(sort file2) > $@

In my GNU Make 3.80 this will give an error since it uses the shellinstead of bashto execute the commands.

在我的 GNU Make 3.80 中,这将产生错误,因为它使用shell代替bash来执行命令。

回答by derobert

From the GNU Make documentation,

从 GNU Make 文档中,

5.3.1 Choosing the Shell
------------------------

The program used as the shell is taken from the variable `SHELL'.  If
this variable is not set in your makefile, the program `/bin/sh' is
used as the shell.

So put SHELL := /bin/bashat the top of your makefile, and you should be good to go.

所以放在SHELL := /bin/bash你的makefile的顶部,你应该很高兴。

BTW: You can also do this for one target, at least for GNU Make. Each target can have its own variable assignments, like this:

顺便说一句:您也可以为一个目标执行此操作,至少对于 GNU Make。每个目标都可以有自己的变量分配,如下所示:

all: a b

a:
    @echo "a is $
a is /bin/sh
b is /bin/bash
" b: SHELL:=/bin/bash # HERE: this is setting the shell for b only b: @echo "b is $
bash -c "diff <(sort file1) <(sort file2) > $@"
"

That'll print:

这将打印:

bash -c "ls -al"

See "Target-specific Variable Values" in the documentation for more details. That line can go anywhere in the Makefile, it doesn't have to be immediately before the target.

有关更多详细信息,请参阅文档中的“特定于目标的变量值”。该行可以位于 Makefile 中的任何位置,不必紧接在目标之前。

回答by Chris Lutz

You can call bashdirectly, use the -cflag:

您可以bash直接调用,使用-c标志:

ls -al

Of course, you may not be able to redirect to the variable $@, but when I tried to do this, I got -bash: $@: ambiguous redirectas an error message, so you may want to look into that before you get too into this (though I'm using bash 3.2.something, so maybe yours works differently).

当然,您可能无法重定向到变量 $@,但是当我尝试执行此操作时,我收到-bash: $@: ambiguous redirect一条错误消息,因此您可能需要在深入了解之前查看它(尽管我是使用 bash 3.2.something,所以也许你的工作方式不同)。

回答by paxdiablo

You can call bash directly within your Makefile instead of using the default shell:

您可以直接在 Makefile 中调用 bash 而不是使用默认 shell:

your-target: $(eval SHELL:=/bin/bash)
    @echo "here shell is $##代码##"

instead of:

代替:

##代码##

回答by Menno Smits

If portability is important you may not want to depend on a specific shell in your Makefile. Not all environments have bash available.

如果可移植性很重要,您可能不想依赖 Makefile 中的特定 shell。并非所有环境都可以使用 bash。

回答by Bill G

There is a way to do this without explicitly setting your SHELL variable to point to bash. This can be useful if you have many makefiles since SHELL isn't inherited by subsequent makefiles or taken from the environment. You also need to be sure that anyone who compiles your code configures their system this way.

有一种方法可以在不显式设置 SHELL 变量以指向 bash 的情况下执行此操作。如果您有许多 makefile,这会很有用,因为 SHELL 不会被后续的 makefile 继承或从环境中获取。您还需要确保编译您的代码的任何人都以这种方式配置他们的系统。

If you run sudo dpkg-reconfigure dashand answer 'no' to the prompt, your system will not use dash as the default shell. It will then point to bash (at least in Ubuntu). Note that using dash as your system shell is a bit more efficient though.

如果您运行sudo dpkg-reconfigure dash并在提示中回答“否”,您的系统将不会使用 dash 作为默认 shell。然后它将指向 bash(至少在 Ubuntu 中)。请注意,使用 dash 作为您的系统外壳会更有效一些。

回答by Nicolas Marshall

One way that also works is putting it this way in the first line of the your target:

一种同样有效的方法是将它放在目标的第一行中:

##代码##