sh-3.2双倍与四倍反斜杠

时间:2016-07-09 14:40:47

标签: bash shell escaping sh backslash

我在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 \\\\\\\\\\\\
\\\

1 个答案:

答案 0 :(得分:2)

您看到bash的POSIX和echo实现之间存在差异。简而言之,POSIX echo会扩展某些转义字符,而bash不会专门处理反斜杠,除非使用-e选项。此外,bashsh运行时使用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版本将\\视为一对字面反斜杠。