sh-3.2 双反斜杠与四反斜杠

sh-3.2 double vs quadruple backslash

我在 OS X 10.11.5,我的系统上有一个 /bin/bash 版本 3.2.57。 /bin/sh 报告同样的事情,表明 /bin/sh 真的是 bash 3.2.

我的 /bin/sh 表现出一些奇怪的行为:echo \ 给出了一个反斜杠(如预期的那样),但是 echo \\ also 给出了 \ 作为输出,你需要 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 \\\\\\
\\

您看到了 echo 的 POSIX 和 bash 实现之间的区别。简而言之,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

单引号只是一个 shorthand,用于转义包含在 in 中的每个字符。对上述所有内容使用显式转义而不是单引号:

# POSIX
$ echo \a\\n\b
a
b
# bash
$ echo \a\\n\b
a\nb
$ echo -e \a\\n\b
a
b

双引号类似于单引号,除了 shell 首先处理一组非常有限的转义字符。这是因为 $ 在双引号内被特殊处理,表示参数扩展。您可以转义 $ 来防止这种情况,您可以转义反斜杠以防止 it 转义后面的字符。在所有其他情况下,反斜杠按字面意思处理并传递给 echo.

$ foo=5
$ echo "$foo"
5
$ echo "$foo"
$foo
$ echo "\$foo"

$ echo "\$foo"
$foo
$ echo "\t"
\t

除此之外,每个 shell 如何创建 echo \\?首先,两个 shell 都执行引号删除以消除引号和转义反斜杠。第一个反斜杠转义第二个,第三个反斜杠转义第四个,只留下一对文字反斜杠作为 echo 的参数。 echo 的 POSIX 版本将 \ 视为文字反斜杠,而 bash 版本将 \ 视为一对文字反斜杠。