我在OS X 10.11.5上,我的系统上有/bin/bash
,版本为3.2.57。 /bin/sh
报告相同的事情,表明/bin/sh
确实是bash 3.2。
我的/bin/sh
表现出一些奇怪的行为:echo \\
提供一个反斜杠(如预期的那样),但echo \\\\
也给出\
作为输出,你需要6个反斜杠来获得两个作为输出。示范:
>> /bin/bash
~$ echo \\
\
~$ echo \\\\
\\
~$ echo \\\\\\
\\\
~$ exit
>> /bin/bash --posix
~$ echo \\
\
~$ echo \\\\
\\
~$ echo \\\\\\
\\\
~$ exit
>> /bin/sh
sh-3.2$ echo \\
\
sh-3.2$ echo \\\\
\
sh-3.2$ echo \\\\\\
\\
sh-3.2$ exit
>> /bin/sh --posix
sh-3.2$ echo \\
\
sh-3.2$ echo \\\\
\
sh-3.2$ echo \\\\\\
\\
sh-3.2$ exit
>> /bin/sh --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.
>> /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.
问题:为什么不echo \\\\
在/bin/sh
中提供两个反斜杠作为输出,而在/bin/bash
中呢?
更多信息:
sh-3.2$ echo \\
\
sh-3.2$ echo \\\\
\
sh-3.2$ echo \\\\\\
\\
sh-3.2$ echo \\\\\\\\
\\
sh-3.2$ echo \\\\\\\\\\
\\\
sh-3.2$ echo \\\\\\\\\\\\
\\\
答案 0 :(得分:2)
您看到bash
的POSIX和echo
实现之间存在差异。简而言之,POSIX echo
会扩展某些转义字符,而bash
不会专门处理反斜杠,除非使用-e
选项。此外,bash
在sh
运行时使用POSIX实现,或者在您明确设置xpg_echo
选项以使用POSIX版本时使用它。
# POSIX
$ echo 'a\nb'
a
b
# bash
$ echo 'a\nb'
a\nb
$ echo -e 'a\nb'
a
b
单引号只是转义包含在其中的每个字符的简写。使用显式转义而不是单引号用于以上所有:
# POSIX
$ echo \a\\\n\b
a
b
# bash
$ echo \a\\\n\b
a\nb
$ echo -e \a\\\n\b
a
b
双引号类似于单引号,但shell首先处理一组非常有限的转义字符。这是因为$
在双引号内特别处理,表示参数扩展。您可以转义$
以阻止此操作,并且可以转义反斜杠以防止它转义后续字符。在所有其他情况下,反斜杠都按字面处理并传递给echo
。
$ foo=5
$ echo "$foo"
5
$ echo "\$foo"
$foo
$ echo "\\$foo"
\5
$ echo "\\\$foo"
\$foo
$ echo "\t"
\t
除此之外,每个shell如何创建echo \\\\
?首先,两个shell执行引用删除以消除引号和转义反斜杠。第一个反斜杠转义第二个,第三个转义第四个,只留下一对文字反斜杠作为echo
的参数。 POSIX版echo
将\\
视为字面反斜杠,而bash
版本将\\
视为一对字面反斜杠。