bash Makefile `echo -n' 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11675070/
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
Makefile `echo -n' not working
提问by Chris
I am trying to have my Makefile echo text without the trailing new line, but am unable to. I am experiencing the behavior on OS X (on Linux everything works as expected).
我试图让我的 Makefile 回显文本没有尾随的新行,但我不能。我在 OS X 上遇到了这种行为(在 Linux 上一切都按预期工作)。
Makefile
生成文件
a:
@echo -n "hello"
b:
@echo -n hello
c:
@/bin/echo -n "hello"
Output:
输出:
$make a
-n hello
$make b
hello$make c
hello$
In other words, the make a
is broken. What exactly is happening? Is make using a built-in echo? Clearly the presence of the double quotes changes the behavior, but why?
换句话说,make a
坏了。究竟发生了什么?是否使用内置回声?显然双引号的存在会改变行为,但为什么呢?
Update
更新
As discovered by @chepner, using the full path to /bin/echo
in the makefile understands the -n flag correctly.
正如@chepner 所发现的那样,使用/bin/echo
makefile 中的完整路径可以正确理解 -n 标志。
采纳答案by chepner
Something about the quotes confuses make
. Your code behaves the same for me, but the following works as expected:
关于引号的一些东西令人困惑make
。你的代码对我来说是一样的,但以下按预期工作:
help:
@echo -n Shouldn\'t print a newline
Hardcoding the path to the executable also works:
硬编码可执行文件的路径也有效:
help:
@/bin/echo -n "Shouldn't print a newline"
The Mac OS X man page for echo
, while discussing the existence of shell built-in echo
s, mentions that the echo
of sh(1)
does not support the -n
option, but that fails to explain (to me, anyway) why my first alternative works.
的 Mac OS X 手册页echo
,在讨论 shell 内置echo
s的存在时,提到echo
ofsh(1)
不支持该-n
选项,但这未能解释(无论如何)为什么我的第一个替代方案有效。
Confirmation that make
is using sh
to execute the commands by default. In
该确认make
是使用sh
默认情况下执行命令。在
SHELL = bash
help:
@echo -n "Shouldn't print a newline"
@echo -n Shouldn\'t print a newline
both echo statements behave the same (no newlines printed). So without that variable, we have bash
pretending to be sh
, but evaluating the two lines differently. Question 1: why? Question 2: is the second line the native bash
echo or /bin/echo
, rather than the emulated sh
echo
?
两个 echo 语句的行为相同(不打印换行符)。所以没有那个变量,我们bash
假装是sh
,但以不同的方式评估这两行。问题一:为什么?问题 2:第二行是本机bash
echo 还是/bin/echo
,而不是 emulated sh
echo
?
回答by Nicolas Dudebout
The problem comes from the unfortunateinteraction of two facts.
问题来自两个事实的不幸相互作用。
First, make
has two modes of operations depending on the complexity of the recipe to be run:
首先,make
根据要运行的配方的复杂程度,有两种操作模式:
- If the command is easy,
make
will directly run the recipe with its builtin commands. This is what happens in yourb
case. - If the command is complex,
make
will spawn a shell to interpret and run the recipe. This is what happens in youra
case.
- 如果命令很简单,
make
将使用其内置命令直接运行配方。这就是你的b
情况。 - 如果命令很复杂,
make
将产生一个 shell 来解释和运行配方。这就是你的a
情况。
Second, make
uses /bin/sh
as a shell but the functionality of /bin/sh
is implemented differently on Mac OS X and Linux:
其次,make
采用/bin/sh
作为外壳,但的功能/bin/sh
的实现方式不同在Mac OS X和Linux:
- On Mac OS X, the functionality of
/bin/sh
is implemented bybash
. Also on Mac OS X,bash
is compiled with--enable-strict-posix-default
. One consequence of this flag is that theecho
command does not understand the-n
flag. - On Linux, the functionality of
/bin/sh
is implemented bydash
which is less strict with respect to POSIX specification. Therefore the flag-n
is implemented in theecho
command.
- 在 Mac OS X 上, 的功能
/bin/sh
由bash
. 同样在 Mac OS X 上,bash
使用--enable-strict-posix-default
. 此标志的一个后果是echo
命令不理解该-n
标志。 - 在 Linux 上, 的功能
/bin/sh
是由dash
POSIX 规范实现的。因此该标志-n
是在echo
命令中实现的。
BTW, the Makefile buitlin echo
command understands the -n
flag which explains why the b
case always works.
顺便说一句,Makefile buitlinecho
命令理解-n
解释为什么这种b
情况总是有效的标志。
The clean and portable way of fixing your problem is to replace your @echo -n
recipes with @printf
recipes.
解决问题的干净且便携的方法是@echo -n
用@printf
食谱替换您的食谱。
回答by pizza
echo is a bash shell builtin, but when you run it from makefile, it is the program version
echo 是一个内置的 bash shell,但是当你从 makefile 运行它时,它是程序版本