Makefile`echo -n'不起作用

Chr*_*ris 27 bash makefile echo

我试图让我的Makefile回显文本没有尾随的新行,但我无法.我正在体验OS X上的行为(在Linux上,一切都按预期工作).

Makefile文件

a:
    @echo -n "hello"

b:
    @echo -n hello

c:
    @/bin/echo -n "hello"
Run Code Online (Sandbox Code Playgroud)

输出:

$make a
-n hello
$make b
hello$make c
hello$
Run Code Online (Sandbox Code Playgroud)

换句话说,它make a被打破了.究竟发生了什么?是使用内置回声吗?很明显,双引号的存在改变了行为,但为什么呢?

更新

正如@chepner所发现的那样,使用/bin/echomakefile中的完整路径正确理解-n标志.

Nic*_*out 25

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

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

  • 如果命令很简单,make将使用其内置命令直接运行配方.这就是你的b情况.
  • 如果命令很复杂,make将生成一个shell来解释并运行配方.这就是你的a情况.

其次,make采用/bin/sh作为外壳,但的功能/bin/sh的实现方式不同在Mac OS X和Linux:

  • 在Mac OS X上,功能/bin/sh是通过实现的bash.同样在Mac OS X上,使用bash编译--enable-strict-posix-default.该标志的一个结果是该echo命令不理解该-n标志.
  • 在Linux中,的功能/bin/sh是通过执行dash这是相对于POSIX规范不那么严格.因此,该标志-necho命令中实现.

顺便说一下,Makefile buitlin echo命令可以理解该-n标志,该标志解释了b案例始终有效的原因.

解决问题的清洁和便携方式是@echo -n@printf食谱替换您的食谱.

  • printf为+1,效果很好. (4认同)

che*_*ner 18

关于报价的一些事情令人困惑make.您的代码对我来说行为相同,但以下工作方式符合预期:

help:
        @echo -n Shouldn\'t print a newline
Run Code Online (Sandbox Code Playgroud)

硬编码可执行文件的路径也有效:

help:
        @/bin/echo -n "Shouldn't print a newline"
Run Code Online (Sandbox Code Playgroud)

对于Mac OS X的手册页echo,一边讨论壳的存在,内置echoS,提到了echosh(1)不支持的-n选项,但无法解释(对我来说,反正)为什么我的第一替代作品.


该确认make是使用sh默认情况下执行命令.在

SHELL = bash
help:
        @echo -n "Shouldn't print a newline"
        @echo -n Shouldn\'t print a newline
Run Code Online (Sandbox Code Playgroud)

两个echo语句表现相同(没有打印换行符).所以没有那个变量,我们bash假装是sh,但是对这两行进行不同的评估.问题1:为什么?问题2:第二行是原生bash回声还是/bin/echo,而不是模拟sh echo