为什么这里文档甚至在注释行上也尝试 shell 替换?

为什么这里文档甚至在注释行上也尝试 shell 替换?

我想看看一些 ASCII 艺术在终端中的样子:

$ cat <<EOF                                                                                                                                                                                  
> #          ____         _
> #  _   _  / __/  ___ _ | |_
> # | | | |/ /    /  _` || __|
> # | |_| |\ \__ 

答案1

这比 bash 更通用。在 POSIX shell 中,您的EOF被称为单词,在讨论中此处文档:

如果没有字符单词被引用时,此处文档的所有行都应扩展以进行参数扩展、命令替换和算术扩展。在这种情况下,<backslash>在输入中表现为<backslash>在双引号内(请参阅双引号)。但是,双引号字符 ( '"') 不应在此处文档中进行特殊处理,除非双引号出现在"$()""``"或 中"${}"

引用是使用单引号、双引号或反斜杠字符完成的。 POSIX 在讨论中提到了here-documents引用:

各种引用机制包括转义字符、单引号和双引号。这里的文档代表了另一种引用形式;看此处文档

理解字符处理缺失的关键#是here-documents的定义:

允许重定向shell 输入文件中包含的行数

也就是说,shell 没有赋予数据任何意义(除了可能的参数扩展等),因为数据是重定向到另一个程序:cat,它不是 shell 解释器。如果您重定向到外壳程序,结果将是 shell 可以对数据执行的任何操作。

答案2

在此处的文档中没有注释行。

man bash:

不对 word 执行任何参数和变量扩展、命令替换、算术扩展或路径名扩展。如果word中的任何字符被引用,则分隔符是word删除引号的结果,并且此处文档中的行不会被扩展。如果 word 不加引号,则此处文档的所有行都会进行参数扩展、命令替换和算术扩展,字符序列 \ 被忽略,并且必须使用 \ 来引用字符 \、$ 和 `。

所以你需要:

cat <<"EOF"

相关内容