为什么 sed 的输出不与多个反斜杠一起存储在 bash 中?

Why isn't sed's output stored with its multiple backslashes in bash?

我试图将 sed 的输出存储到一个变量中,但是输出与我期望的不同。

我的测试是下面的

$ foo="this is (foo)"
$ x="$(sed 's/(/\\(/g' <<< $foo)"

预期的结果是:

$ echo $x
this is \(foo)

我得到的结果是:

$ echo $x
this is \(foo)

但是,当我没有将输出分配给变量时,结果就是预期的结果:

$ sed 's/(/\\(/g' <<< $foo
this is \(foo)

为什么我的输出存储失败?

注意:

我还尝试了以下命令行,它们都以相同的结果结束:

$ x=`sed 's/(/\\(/g' <<< $foo`

$ x=$(sed 's/(/\\(/g' <<< $foo)

$ x=`echo $foo | sed 's/(/\\(/g'`

$ x=$(echo $foo | sed 's/(/\\(/g')

不要相信 echo:POSIX 规范在其实现中留下了足够的余地,您不能相信它的输出能够正确表示手头的值。相反,使用 printf:

foo="this is (foo)"
x="$(sed 's/(/\\(/g' <<<"$foo")"
printf '%s\n' "$x"

...正确发出...

this is \(foo)

来自the POSIX specification for echo,重点补充:

The following operands shall be supported:

string

A string to be written to standard output. If the first operand is -n, or if any of the operands contain a backslash ( '\' ) character, the results are implementation-defined.

同样,来自同一文档的“应用程序使用”部分:

It is not possible to use echo portably across all POSIX systems unless both -n (as the first argument) and escape sequences are omitted.

The printf utility can be used portably to emulate any of the traditional behaviors of the echo utility [...]