Heredoc(Here Document)是一种许多编程和脚本语言都使用的输入字面量。Heredoc 最初是在 UNIX Shell 中使用的,至今仍非常流行,并且被所有主流的 Linux Shell(如 zsh、bash、tsh 等)所支持。Heredoc 的符号是 ‘<<',即两个左尖括号。
语法
<< 'Delimiter'
---语句/注释---
'Delimiter'
Heredoc 后跟一个分隔符,接着是内容块。该块以相同的分隔符结束。
我们可以使用各种分隔符,例如 BLOCK COMMENT 等。在这篇文章中,我们将讨论一些主要的且常用的分隔符。
目录
结合 SSH 使用 Heredoc
作为一个便捷的工具,Heredoc 可以结合 SSH 使用,以便在远程服务器上执行多个命令。让我们通过一个例子来看看。
ssh user@ <<EOF
"SSH connected user name: \$USER"
"Current user name: $USER"
EOF
这里的 INLINECODEe3c6a74a 将被替换为 ssh 服务器的 IP 地址,上面代码中 INLINECODE8a38cd9f 前面的 user 将是需要访问的用户名。产生的输出如下:
在这个例子中,我们在 Heredoc 块中简单地向 SSH 连接传递了两个命令,用于显示客户端和服务器机器的用户名。通过这种方式,我们可以使用 Heredoc 在单个块中执行多个命令。
这里需要注意的一点是,SSH 连接会一直保持连接状态,直到 Heredoc 中的所有语句都执行完毕。
使用 Heredoc 执行命令
块分隔符位于 << 之后,随后是一个 shell 命令。这允许用户从单个块中执行多个命令,或者使用单个命令执行多个语句。请看下面的例子,我们使用 CAT shell 命令来打印多行输入。
#!/bin/bash
cat << BLOCK
This is a block delimiter
Used with a CAT command.
BLOCK
上面的 shell 脚本将在终端中显示这两行。请看下面的输出。
可以看到,heredoc.sh 包含了上面的代码示例,在执行时,它显示了 BLOCK 分隔符块的内容,就像处理单行内容一样。
在 Heredoc 中使用 ‘-‘ – 抑制空白/制表符
Heredoc (<<) 在默认设置下不会抑制额外的制表符和空格。我们在 Heredoc 后添加连字符 (-) 来抑制制表符,但不能抑制空格。请看下面的例子。
#!/bin/bash
cat <<- BLOCK
This is block delimiter.
This is a tabbed line.
BLOCK
输出将会是:
可以看到,BLOCK 第一行的空格没有被抑制,但是在 Heredoc 后添加连字符后,第二行的制表符被抑制了。
COMMENT 分隔符
在 Shell 脚本中,注释使用 INLINECODE7e7e07b2 字面量表示。然而,对于多行注释,在每一行都加上 INLINECODE17f182fe 并不是一种高效的方法。为了以一种更编程化的方式来做同样的事情,我们可以使用带有 COMMENT 分隔符的 Heredoc。请看下面的例子来理解如何操作。
#!/bin/bash
<< COMMENT
Multiline comment 1
Multiline comment 2
Multiline comment 3
COMMENT
echo "Comments added"
Output:
现在,在上面的脚本中,我们添加了虚拟注释,后面跟着一个打印 语句,显示消息注释已添加。上面的输出显示了同样的结果。
在 Heredoc 文本中使用变量
我们可以在 bash 中使用 Heredoc 执行变量替换。变量的使用类似于普通的 bash 脚本,通过使用 ${} 符号。请看下面的例子。
#!/bin/bash
name=$1
cat << EOF
The name of the owner is ${name}
EOF
在这里,我们将在脚本执行期间从用户那里获取名字,然后将其显示出来。
Output:
转义特殊字符
我们可以使用反斜杠 (\) 字面量来转义整个块或块中特定行的特殊字符。
在转义整个块时,我们可以执行以下操作之一:
- 在分隔符前加上反斜杠 \。
- 将分隔符用单引号或双引号括起来。
请看下面的例子。
#!/bin/bash
name=$1
cat << BLOCK
The name is ${name}
this line ha\$ \$pecial character\$.
BLOCK
echo
cat << \BLOCK2
The name is ${name}
this linr has special characters.
BLOCK2
echo
cat << 'BLOCK3'
The name is ${name}
this linr has special characters.
BLOCK3
Output: