cat*_*cat 6 bash cat variable-substitution
我想看看一些 ASCII 艺术在终端中的样子:
$ cat <<EOF
> # ____ _
> # _ _ / __/ ___ _ | |_
> # | | | |/ / / _` || __|
> # | |_| |\ \__ (_| || |_
> # | _,_| \___\ \___,_| \__|
> # |_/
> #
> EOF
bash: bad substitution: no closing "`" in ` || __|
# | |_| |\ \__ (_| || |_
# | _,_| \___\ \___,_| \__|
# |_/
#
Run Code Online (Sandbox Code Playgroud)
该#octothorpes在那里或许,但现在我很困惑。
$ cat <<EOF
> # echo hi
> EOF
# echo hi
Run Code Online (Sandbox Code Playgroud)
正如预期的那样。
然而:
$ cat <<EOF
> # `echo hello`
> EOF
# hello
Run Code Online (Sandbox Code Playgroud)
所以bash得到扩展``和$( )之前cat,但它不关心#评论?这种行为背后的解释是什么?
Tho*_*key 16
这比 bash 更通用。在 POSIX shell 中,您在here-documents的讨论中EOF被称为word:
如果word中没有引用字符,则此处文档的所有行都应进行参数扩展、命令替换和算术扩展。在这种情况下,
<backslash>输入中的 表现为<backslash>内部双引号(请参阅双引号)。但是,双引号字符 ('"') 在 here-document 中不应被特殊对待,除非双引号出现在"$()"、"``"、 或 中"${}"。
引用是使用单引号、双引号或反斜杠字符完成的。POSIX 在讨论引用时提到了 here-documents :
各种引用机制是转义字符、单引号和双引号。here-document 代表了另一种引用形式;请参阅此处文档。
理解#字符处理缺失的关键是here-documents的定义:
允许重定向shell 输入文件中包含的行
也就是说,shell 没有赋予数据任何意义(除了可能的参数扩展等),因为数据被重定向到另一个程序:cat,它不是 shell 解释器。如果您重定向到shell program,结果将是 shell 可以对数据执行的任何操作。
在此处的文档中没有注释行。
man bash:
不会对 word 执行参数和变量扩展、命令替换、算术扩展或路径名扩展。如果word中的任何字符被引用,则分隔符是对word去除引用的结果,并且here-document中的行不展开。如果 word 不加引号,here-document 的所有行都经过参数扩展、命令替换和算术扩展,字符序列 \ 被忽略,并且必须使用 \ 来引用字符 \、$ 和 `。
所以你需要:
cat <<"EOF"
Run Code Online (Sandbox Code Playgroud)