Section 20.1: 在文档里转义执行命令

ssh -p 21 example@example.com <<EOF
    echo 'printing pwd'
    echo "\$(pwd)"
    ls -a
    find '*.txt'
EOF

$ 被转义是因为我们不希望它被当前 shell 展开,即 $(pwd) 将在远程 shell 上执行。

另一种方法

ssh -p 21 example@example.com <<'EOF'
    echo 'printing pwd'
    echo "$(pwd)"
    ls -a
    find '*.txt'
EOF

注意:结束符 EOF 应位于行首(前无空格)。如果需要缩进,可以使用制表符(如果以 <<- 开头)。更多信息,请参阅此处的缩进文档和限制字符串示例。

Section 20.2: 这是文档的缩进

您可以使用制表符缩进此处文档中的文本,您需要使用 '<<-' 重定向运算符而不是 '<<':

$ cat <<- EOF
    This is some content indented with tabs `\t`.
    You cannot indent with spaces you __have__ to use tabs.
    Bash will remove empty space before these lines.
    __Note__: Be sure to replace spaces with tabs when copying this example.
EOF

This is some content indented with tabs _\t_.
You cannot indent with spaces you __have__ to use tabs.
Bash will remove empty space before these lines.
__Note__: Be sure to replace spaces with tabs when copying this example.

一个实际用例(如 man bash 中所述)是在 shell 脚本中,例如:

if cond; then
    cat <<- EOF
    hello
    there
    EOF
fi

习惯上缩进代码块中的行,就像这个 if 语句一样,以获得更好的可读性。如果没有 '<<-' 运算符语法,我们将被迫编写上述代码,如下所示:

if cond; then
        cat << EOF
hello
there
EOF
fi

这读起来非常不愉快,在更复杂的现实脚本中情况会变得更糟。

Section 20.3: 创建文件

此处文档的一个经典用途是通过键入文件的内容来创建文件:

cat > fruits.txt << EOF
apple
orange
lemon
EOF

此处的文档是 '<< EOF' 和 'EOF' 之间的行。此此处的文档成为 'cat' 命令的输入。'cat' 命令仅输出其输入,并使用输出重定向运算符 '>' 重定向到文件 'fruits.txt'。

因此,fruits.txt 文件将包含以下几行:

apple
orange
lemon

输出重定向的通常规则适用:如果 fruits.txt 之前不存在,则将创建它。如果它以前存在,它将被截断。

Section 20.4: 重定向字符串

Version ≥ 2.05b

你可以使用重定向字符串提供命令,如下所示:

$ awk '{print $2}' <<< "hello world - how are you?"
world

$ awk '{print $1}' <<< "hello how are you
> she is fine"
hello
she

你也可以给 while 循环一个 here 字符串:

$ while IFS=" " read -r word1 word2 rest
> do
> echo "$word1"
> done <<< "hello how are you - i am fine"
hello

Section 20.5: 使用 sudo 运行多个命令

sudo -s <<EOF
    a='var'
    echo 'Running serveral commands with sudo'
    mktemp -d
    echo "\$a"
EOF

$a 需要转义以防止它被当前 shell 扩展

Or

sudo -s <<'EOF'
    a='var'
    echo 'Running serveral commands with sudo'
    mktemp -d
    echo "$a"
EOF

Section 20.6: 限制字符串

  • heredoc 使用限制字符串来确定何时停止使用 input。终止限制字符串必须

  • 位于一行的开头。

  • 成为该行上的唯一文本 注意:如果您使用 <<- limitstring 可以以制表符 t 为前缀

Correct:

cat <<limitstring
line 1
line 2
limitstring

This will output:

line 1
line 2

Incorrect use:

cat <<limitstring
line 1
line 2
limitstring

由于最后一行的 'limitstring' 并不完全位于该行的开头,因此 shell 将继续等待进一步的输入,直到它看到一行以 limitstring 开头且不包含任何其他内容。只有这样,它才会停止等待输入,并继续将 here-document 传递给 'cat' 命令。

请注意,当您在初始 limitstring 前面加上连字符时,在解析之前会删除行开头的任何制表符,因此数据和 limit 字符串可以用制表符缩进(以便于 shell 脚本中阅读)。

cat <<-limitstring
        line 1 has a tab each before the words line and has
                line 2 has two leading tabs
        limitstring

将产生

line 1 has a tab each before the words line and has
line 2 has two leading tabs

删除了前导选项卡(但不包括内部选项卡)。