heredoc 和 here string 简介
1. 概述
在本教程中,我们将了解 Linux 的此处文档和此处字符串的语法。除此之外,我们还将演示与它们相关的几种常见使用模式。
2.定义
在 Linux 中,here document(通常也称为 heredoc)是指一个特殊的代码块,其中包含将被重定向到命令的多行字符串。另一方面,here string 是heredoc 的更简单版本,提供了一些类似的功能,尽管不如后者强大。
要了解使用其中任何一个的好处,假设我们想通过 ssh 向另一个远程系统发送几行命令。除此之外,我们假设需要在没有交互式终端的情况下发送命令。我们可以通过以下方式轻松实现:
ssh -T itcodingman@blogdemo "touch log1.txt"
ssh -T itcodingman@blogdemo "touch log2.txt"
在上面的简单示例中,我们在远程系统上通过 ssh 执行两行代码。但是,如果我们有更多的命令要执行,上面的解决方案就会变得混乱和冗长。为了使其更简洁,我们可以将其替换为heredoc:
ssh -T itcodingman@blogdemo << EOF
touch log1.txt
touch log2.txt
EOF
上面的命令以非常简洁的形式执行与前一个命令相同的操作。
3. 这里文档
3.1. 语法
一个heredoc 由’«’ 重定向操作符和一个定界符组成。在分隔符标记之后,可以定义字符串行来形成内容。最后,将分隔符标记放在末尾作为终止符。分隔符标记可以是任何值,只要它足够独特,不会出现在内容中。例如,我们可以创建一个由几行简单字符串组成的heredoc,并通过命令cat将其输出:
cat <<EOF
This is line1
Another line
Finally 3rd line
EOF
在此示例中,我们将分隔符标记定义为“EOF”。另一方面,夹在一对“EOF”标记之间的三行字符串作为内容。然后,将这三个字符串输入cat命令,然后将它们打印到控制台。
请注意,定界符标记不会出现在 heredoc 的输出中。
3.2. 制表符抑制
通常,我们使用制表符在heredoc 中添加缩进,以便更容易阅读,尤其是在shell 脚本中。但是,我们很少希望选项卡成为输出的一部分。为了抑制输出中的制表符缩进,我们可以在重定向运算符 ‘«’ 前加上一个破折号。
具体来说,如果我们执行以下操作:
cat <<-EOF
This message is indented
This message is double indented
EOF
我们将在控制台上获得以下输出:
This message is indented
This message is double indented
但是,即使使用破折号前缀,也不会抑制空格。
3.3. 此处带有参数替换的文档
我们还可以通过使用变量来参数化heredoc,从而使其动态化。例如,我们可以根据参数的值更改heredoc的输出:
cat <<EOF
Hello ${USER}
EOF
然后将根据变量USER的值自定义输出。
3.4. 此处带有命令替换的文档
除了参数,heredoc 还支持在其内容中进行命令替换。例如,假设我们要自定义输出,使其始终打印当前日期和时间:
cat <<EOF
Hello! It is currently: $(date)
EOF
现在,每当我们运行上面的命令时,输出将始终包含当前日期和时间。
3.5. 使用 Here Document 将参数传递给函数
我们还可以使用heredoc 将参数传递给需要交互式用户输入的函数。例如,让我们考虑以下函数:
LoginToModule()
{
read -p "Username: " username
read -p "Passphrase: " passphrase
echo "Obtained input ${username} and ${passphrase}"
}
调用时,该函数将等待用户输入以捕获变量username和 passphrase的值:
LoginToModule
Username: blogdemo
Passphrase: secret
Obtained input blogdemo and secret
除了以交互方式提供输入之外,我们还可以构造一个heredoc来传递值:
LoginToModule <<EOF
adminuser
adminpassphrase
EOF
3.6. 转义此处文档中的特殊字符
默认情况下,像 $、\ 和 ` 这样的特殊字符在 heredoc 中被解释,以便参数和命令替换等功能可以工作。要转义它们,我们可以在特殊字符前加上反斜杠“\”:
cat <<EOF
Some Special Characters: \$ \\ \`
EOF
在我们想要转义所有特殊字符的情况下,我们可以引用分隔符标记或在分隔符标记前加上反斜杠。
转义所有特殊字符的三种不同方法是:
cat <<'EOF'
Some Special Characters: $ \ `
EOF
cat <<"EOF"
Some Special Characters: $ \ `
EOF
cat <<\EOF
Some Special Characters: $ \ `
EOF
需要注意的一件重要事情是,当所有特殊字符都被转义时,参数和命令替换将不再起作用。原因是参数和命令替换中使用的特殊字符将被转义,而不是解释。
3.7. 使用此处文档禁用代码块
在 shell 脚本中,禁用代码块的一种方法是在代码的每一行前面加上一个“#”,以使它们成为注释。但是,我们可以使用带有虚拟命令 ‘:’ 的 heredoc 更有效地做到这一点。例如,我们可以在 shell 脚本中禁用几行代码:
#!/bin/bash
# disable-with-heredoc.sh
: <<'DISABLED'
echo "This line will not show up in the console.
echo "Neither will this line.
DISABLED
echo "This line will be printed to the console
通过将代码块转换为heredoc 并将其重定向到虚拟命令’:’,我们基本上阻止了代码块的执行。我们已经封闭了分隔符标记来转义 content 中的所有特殊字符。这样做是为了防止执行任何命令替换,从而防止任何意外的副作用。
4. 这里字符串
这里的字符串与heredoc 非常相似,只是前者是heredoc 的一个更简单的版本。出于这个原因,这里的 string 不需要分隔符 token。每当我们需要一种快速的方法将一些字符串重定向到命令中时,它通常是首选。
4.1. 语法
为了构造here字符串,我们使用“«<”运算符将字符串重定向到命令中。具体来说,语法是:
COMMAND <<< $VAR
它本质上所做的是扩展变量VAR 并将输出字符串重定向到COMMAND。
4.2. 基本用法
这里字符串的最简单形式由一个命令组成,后跟一个“«<”重定向器和一个字符串:
cat <<< "This is a string"
除此之外,我们可以重定向一个包含字符串的变量:
WELCOME_MESSAGE="Welcome to dashboard"
cat <<< $WELCOME_MESSAGE
4.3. 这里是带参数的字符串
与 heredoc 类似,我们也可以使用变量参数化 here 字符串的输出:
cat <<< "Welcome! ${USER}"
4.4. 转义此处字符串中的特殊字符
要转义 $、\ 和 ` 等特殊字符,我们可以用单引号而不是双引号将字符串括起来:
cat <<< 'Display special characters: $ ` \'
如果我们用单引号将此处的字符串括起来,诸如${USER}之类的变量扩展将停止工作。