bash/debian:奇怪的 makefile 行为

Pat*_*the 6 make

我在 TeX 中使用了一个非常简单的 makefile:

test-makefile:
    echo '\newcommand{\seance}{seance1}' > seances/seance.tex
Run Code Online (Sandbox Code Playgroud)

我运行它:

$ make test-makefile 
echo '\newcommand{\seance}{seance1}' > seances/seance.tex
Run Code Online (Sandbox Code Playgroud)

我的问题是在名为“seances”的文件夹中创建的文件不包含它应该包含的前两个字符:

?
ewcommand{\seance}{seance1}
Run Code Online (Sandbox Code Playgroud)

它的第一行是空的。

当然我可以保护第一个 antislash:echo '\\newcommand{\seance}{seance1}等。但在现实世界中它不起作用:我真正的 makefile(我已经发布了一个 ECM)不起作用。

发生什么了?bash/debian 如何误解命令的开头?



顺便一提:

$ bash --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
?
$ cat /etc/debian_version
buster/sid
?
$ uname -a
Linux giljourdan 4.16.0-1-amd64 #1 SMP Debian 4.16.5-1 (2018-04-29) x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 12

echo是解释反斜杠转义的人之一。A\n表示换行符,因此您完全可以理解。后一个反斜杠按原样出现,因为\s它不是有效的转义码。

Make 通过 shell 运行命令,/bin/sh默认使用,在 Debian 上是 dash。Dash 的内置echo函数会处理反斜杠。Bash 没有。(/bin/echoDebian上的外部也不重要,除非您明确运行,否则这并不重要/bin/echo)。

你最好的选择是printf明确使用,它至少是安全的,因为它总是处理反斜杠转义。下面应该总是做同样的事情,\\n在开始时产生一个真正的反斜杠和一个n\n后来产生一个换行符来结束该行。

foo:
        printf '\\newcommand\n' > foo
Run Code Online (Sandbox Code Playgroud)

(或者,如果您想避免处理反斜杠,请使用printf "%s" '\newcommand'

看到问题为什么 printf 比 echo 好?有关echo陷阱的更多详细信息。