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

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

Makefile `echo -n' not working

bashmakefileecho

提问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 ais 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/echoin the makefile understands the -n flag correctly.

正如@chepner 所发现的那样,使用/bin/echomakefile 中的完整路径可以正确理解 -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 echos, mentions that the echoof sh(1)does not support the -noption, but that fails to explain (to me, anyway) why my first alternative works.

的 Mac OS X 手册页echo,在讨论 shell 内置echos的存在时,提到echoofsh(1)不支持该-n选项,但这未能解释(无论如何)为什么我的第一个替代方案有效。



Confirmation that makeis using shto 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 bashpretending to be sh, but evaluating the two lines differently. Question 1: why? Question 2: is the second line the native bashecho or /bin/echo, rather than the emulated shecho?

两个 echo 语句的行为相同(不打印换行符)。所以没有那个变量,我们bash假装是sh,但以不同的方式评估这两行。问题一:为什么?问题 2:第二行是本机bashecho 还是/bin/echo,而不是 emulated shecho

回答by Nicolas Dudebout

The problem comes from the unfortunateinteraction of two facts.

问题来自两个事实的不幸相互作用。

First, makehas two modes of operations depending on the complexity of the recipe to be run:

首先,make根据要运行的配方的复杂程度,有两种操作模式:

  • If the command is easy, makewill directly run the recipe with its builtin commands. This is what happens in your bcase.
  • If the command is complex, makewill spawn a shell to interpret and run the recipe. This is what happens in your acase.
  • 如果命令很简单make将使用其内置命令直接运行配方。这就是你的b情况。
  • 如果命令很复杂make将产生一个 shell 来解释和运行配方。这就是你的a情况。

Second, makeuses /bin/shas a shell but the functionality of /bin/shis 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/shis implemented by bash. Also on Mac OS X, bashis compiled with --enable-strict-posix-default. One consequence of this flag is that the echocommand does not understand the -nflag.
  • On Linux, the functionality of /bin/shis implemented by dashwhich is less strict with respect to POSIX specification. Therefore the flag -nis implemented in the echocommand.
  • 在 Mac OS X 上, 的功能/bin/shbash. 同样在 Mac OS X 上,bash使用--enable-strict-posix-default. 此标志的一个后果是echo命令不理解该-n标志。
  • 在 Linux 上, 的功能/bin/sh是由dashPOSIX 规范实现的。因此该标志-n是在echo命令中实现的。

BTW, the Makefile buitlin echocommand understands the -nflag which explains why the bcase always works.

顺便说一句,Makefile buitlinecho命令理解-n解释为什么这种b情况总是有效的标志。

The clean and portable way of fixing your problem is to replace your @echo -nrecipes with @printfrecipes.

解决问题的干净且便携的方法是@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 运行它时,它是程序版本