为什么 bash here-string 添加尾随换行符?

为什么 bash here-string 添加尾随换行符?

以下示例显示换行符被添加到这里的字符串
为什么要这样做?

xxd -p <<<'a'  
# output: 610a

xxd -p <<<'a
'
# output: 610a0a

答案1

简单的答案是因为 ksh 就是这样编写的(并且 bash 是兼容的)。但这种设计选择是有原因的。

大多数命令都需要文本输入。在 Unix 世界里,文本文件由一系列行组成,每行以换行符结尾。因此在大多数情况下需要最后一个换行符。一个特别常见的情况是通过命令替换获取命令的输出,以某种方式处理它,然后将其传递给另一个命令。命令替换会删除最后的换行符;<<<把一个放回去。

tmp=$(foo)
tmp=${tmp//hello/world}
tmp=${tmp#prefix}
bar <<<$tmp

Bash 和 ksh 无论如何都无法操作二进制数据(它无法处理空字符),因此它们的设施面向文本数据也就不足为奇了。

无论如何,here-string语法<<<主要只是为了方便,就像<<here-documents 一样。如果您不需要添加最后的换行符,请使用echo -n(在 bash 中)或printf和 管道。

答案2

在此处字符串中附加换行符的一种实际情况是在模式处于活动状态read时使用该命令。set -e回想一下,set -e当脚本(或多或少)遇到生成非零状态代码的语句时,会导致脚本终止。考虑read当遇到没有换行符的字符串时生成非零状态代码:

#!/bin/bash
set -e

# The following statement succeeds because here-strings append a newline:
IFS='' read -r <<< 'newline appended'
echo 'Made it here'

# The following statement fails because 'read' returns a non-zero status
# code when no newlines are encountered.
printf 'no newline' | IFS='' read -r
echo 'Did not make it here'

答案3

我认为这是在此处字符串末尾获得换行符的唯一方法,证明:

xxd <<<`echo -ne "a\n"`

看来,here-string 运算符会删除换行符,除非在您提交的语法中给出了换行符。

相关内容