csi*_*ac2 7 bash dash echo quoting
我有一个小的开源项目,出于各种原因,我试图用相当可移植的 shell 脚本编写。它的自动化集成测试检查路径表达式中的敌对字符是否得到正确处理,等等。
/bin/sh
提供的用户bash
在测试中看到失败,我已将其简化为以下内容:
echo "A bug\\'s life"
echo "A bug\\\\'s life"
Run Code Online (Sandbox Code Playgroud)
在 bash 上,它会产生以下预期结果:
A bug\'s life
A bug\\'s life
Run Code Online (Sandbox Code Playgroud)
使用我开发的破折号,它可以执行以下操作:
A bug\'s life
A bug\'s life
Run Code Online (Sandbox Code Playgroud)
我想我没有在 dash 中发现错误,我可能会遗漏一些东西。对此有合理的解释吗?
Sté*_*las 12
在
echo "A bug\\'s life"
Run Code Online (Sandbox Code Playgroud)
因为那些是双引号,并且\
在双引号内是特殊的\
,所以 shell将第一个理解为转义/引用第二个\
. 所以一个A bug\'s life
参数被传递给echo
.
echo "A bug\'s life"
Run Code Online (Sandbox Code Playgroud)
会达到完全一样的。'
在双引号内并不特殊,\
不会被删除,因此它与传递给echo
.
正如为什么 printf 比 echo 好?,echo
实现之间有很多变化。
在符合 UNIX 的实现中,如dash
's echo
builtin¹,\
用于引入转义序列:\n
换行符、\b
退格符、\0123
八进制序列......以及\\
反斜杠本身。
一些(非 POSIX)需要一个-e
选项,或者仅在符合模式下执行(例如bash
's 当使用正确的选项构建时,如sh
OS/X 或SHELLOPTS=xpg_echo
在环境中调用时)。
所以在标准(仅限 Unix 标准;POSIX 未指定行为)中echo
,
echo '\\'
Run Code Online (Sandbox Code Playgroud)
与...一样:
echo "\\\\"
Run Code Online (Sandbox Code Playgroud)
输出一个反斜杠,而在bash
不处于一致性模式时:
echo '\\'
Run Code Online (Sandbox Code Playgroud)
将输出两个反斜杠。
最好避免echo
并使用它printf
:
$ printf '%s\n' "A bug\'s life"
A bug\'s life
Run Code Online (Sandbox Code Playgroud)
在所有printf
实现中,在此实例中的工作原理相同。
¹ dash
'secho
在这方面是合规的,但在echo -n
UNIX 规范 (POSIX + XSI) 要求它输出-n<newline>
.