只要终端反斜杠不存在,在捕获变量中的heredoc的输出后,就会保留heredoc的换行符:
var=$(cat <<-EOF
a
b
c
EOF
)
echo "$var"
a
b
c
然而,当尝试存储反斜杠换行符时,换行符会丢失:
var=$(cat <<-EOF
a \\
b \\
c
EOF
)
echo "$var"
a \b \c
添加额外的反斜杠以进一步转义并没有帮助。
当然,当不在子 shell 中运行时,heredoc 可用于生成以反斜杠换行符结尾的行:
$ cat <<-EOF
a \\
b \\
c
EOF
a \
b \
c
为了避免这个问题,可以添加一个换行符来通过变量的转换生成所需的输出:
var=$(cat <<-EOF
a \\@
b \\@
c
EOF
)
tr -d '@' <<<"$var"
a \
b \
c
是否有更直接的方法来保留在子 shell 中运行的heredocs 中的反斜杠换行符?
答案1
我想知道这是否是 Bash 中的一个错误(或者反斜杠换行符的行为是否只是未定义)。我尝试过的所有其他 shell 都表现出与 Bash 不同的行为:
$ cat nl.sh
echo "1:"
cat <<EOF
a \\
b \\
c
EOF
echo "2:"
var=$(cat <<-EOF
a \\
b \\
c
EOF
)
echo "$var"
输出:
$ bash nl.sh
1:
a \
b \
c
2:
a \b \c
与
$ dash nl.sh
1:
a \
b \
c
2:
a \
b \
c
您可以将代码放入函数的命令替换中,这可能有助于解决解析器的任何问题,例如:
f() {
cat <<EOF
a \\
b
EOF
}
var=$(f)
echo "$var"
答案2
没有直接的方法可以使换行符在此处文档内强制扩展。但是您可以使用包含使用 ANSI 转义序列 ( ) 编码的换行符的变量$'\n'
,并使变量扩展发生在定界文档内。
请注意,这种形式的异教扩展需要将您的分隔'EOF'
符不加引号,即如下所示,
nl=$'\n'
并使用该$nl
变量作为换行符的占位符
var=$(cat <<-EOF
a $nl
b $nl
c
EOF
)
现在可以正确发出
echo "$var"
a
b
c