我在 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/echo
Debian上的外部也不重要,除非您明确运行,否则这并不重要/bin/echo
)。
你最好的选择是printf
明确使用,它至少是安全的,因为它总是处理反斜杠转义。下面应该总是做同样的事情,\\n
在开始时产生一个真正的反斜杠和一个n
,\n
后来产生一个换行符来结束该行。
foo:
printf '\\newcommand\n' > foo
Run Code Online (Sandbox Code Playgroud)
(或者,如果您想避免处理反斜杠,请使用printf "%s" '\newcommand'
)
看到问题为什么 printf 比 echo 好?有关echo
陷阱的更多详细信息。