为什么 Bash 在扩展此处字符串时总是添加换行符?

Why does Bash always add a newline when expanding here strings?

已阅读 Bash 的此功能的以下描述(摘自手册页):

Here Strings

A variant of here documents, the format is:

<<<word

The word is expanded and supplied to the command on its standard input.

我预计此处字符串的解释是 Bash 只是将变量的内容直接传递到命令的标准输入,不加修改。按照这个逻辑,下面的 [1][2] 行实际上是等价的。

[1]~$ printf foo | cat - <(echo end)
fooend
[2]~$ cat - <(echo end) <<<foo
foo
end

然而,Bash 在“扩展”字符串时添加了一个换行符,这是我没有预料到的。即使变量本身以换行符结尾,也会发生这种情况:

[3]~$ printf "foo\n" | cat - <(echo end)
foo
end
[4]~$ cat - <(echo end) <<<foo$'\n'
foo

end

在 4.2.25 和 4.3.30 中测试。

所以我的问题是:Bash 文档中是否指定了这种行为?我可以在脚本中依赖它吗?

不确定,但我相信此处的字符串等同于单行此处文档,因此

cat <<< foo

cat <<EOF
foo
EOF

是等价的。由于 here 文档总是以换行符结尾,因此 here 字符串也应如此。


考虑这里字符串的这个简单用例:

IFS=: read foo bar <<< "a:b"
# foo=a
# bar=b

如果此处的字符串未提供换行符,read 的退出状态将为 1。(参见 printf "foo" | { read; echo $?; }printf "foo\n" | { read; echo $?; }。)

So my question is: is this behavior specified anywhere in Bash docs? Can I depend on it in scripts?

规范现已添加到 Bash Reference Manual:

The result is supplied as a single string, with a newline appended, to the command on its standard input (or file descriptor n if n is specified).