为何使用cat <<< $VAR1会丢失换行符?
为什么变量展开后换行符变成了空格?
先看你给出的两个对比场景:
示例1:正常输出两行内容
$ cat <<< $'Line 1\nLine 2' Line 1 Line 2
示例2:换行符被替换成空格
$ VAR1=$'Line 1\nLine 2' $ cat <<< $VAR1 Line 1 Line 2
你已经通过set | grep VAR1确认了变量VAR1确实存储了带换行符的内容:
$ set | grep VAR1 VAR1=$'Line1\nLine2'
问题根源:不带引号的变量展开会触发「分词」机制
这里的核心差异在于bash处理变量展开的逻辑:
- 示例1里,
$'Line 1\nLine 2'是直接作为<<<的参数,bash会先解析这个ANSI-C转义字符串,生成包含真实换行符的文本,然后直接传递给cat,全程没有额外的分词处理,所以换行符被完整保留。 - 示例2里,
$VAR1是不带引号的变量引用,bash会分两步处理:- 先展开变量,得到包含换行符的原始字符串;
- 然后根据默认的
IFS(内部字段分隔符,默认包含空格、制表符、换行符)进行「分词」——换行符会被当作单词分隔符,把原本的两行文本拆成两个独立的单词; - 最后
<<<会把这些拆分后的单词用空格拼接起来,所以cat接收到的是一行用空格分隔的内容。
解决方法:用双引号包裹变量,阻止分词
只要给变量加上双引号,就能让bash直接使用变量的原始内容,跳过分词步骤:
$ VAR1=$'Line 1\nLine 2' $ cat <<< "$VAR1" Line 1 Line 2
这样就能得到和示例1完全一致的输出了!
内容的提问来源于stack exchange,提问作者Michael Goldshteyn
相关产品推荐
相关产品推荐

