如何在Shell脚本中使用Heredoc?

Here文档(Heredoc)是一种输入或文件流文字,被视为特殊的代码块。这个代码块将被传递给命令进行处理。Heredoc起源于UNIX Shell,可以在shell中找到,如sh、tcsh、ksh、bash、zsh、csh。值得注意的是,其他编程语言如Perl、Ruby、PHP也支持heredoc。

一、Heredoc的结构

Heredoc使用两个尖括号(<<)后跟一个分隔符令牌。相同的分隔符令牌将用于终止代码块。在分隔符内出现的任何内容都被视为代码块。

看下面的示例。我正在将代码块重定向到cat命令。这里,分隔符设置为“BLOCK”,并以相同的“BLOCK”终止。

cat << **BLOCK**
    Hello world
    Today date is $(date +%F)
    My home directory = ${HOME}
**BLOCK**

注意:你应该使用相同的分隔符令牌来开始和终止代码块。

二、创建多行注释

如果你现在在bash中编码,你可能知道bash默认不支持像C或Java那样的多行注释。你可以使用HereDoc来克服这个问题。

这不是bash支持多行注释的内置特性,而只是一种技巧。如果你没有将heredoc重定向到任何命令,解释器将简单地读取代码块,而不会执行任何操作。

<< **COMMENT**
    This is comment line 1
    This is comment line 2
    This is comment line 3
**COMMENT**

多行注释

三、处理空白符

默认情况下,Heredoc不会抑制任何空白字符(制表符、空格)。我们可以通过在(<<)后添加dash (-),然后是一个分隔符,来覆盖这种行为。这将抑制所有的制表符空格,但不会抑制空格。

cat <<- BLOCK
This line has no whitespace.
  This line has 2 white spaces at the beginning.
    This line has a single tab.
        This line has 2 tabs.
            This line has 3 tabs.
BLOCK

处理空格

四、变量和命令替换

Heredoc接受变量替换。变量可以是用户定义的变量或环境变量。

TODAY=$(date +%F)
cat << BLOCK1
# User defined variables
Today date is = ${TODAY}
#Environ Variables
I am running as = ${USER}
My home dir is = ${HOME}
I am using ${SHELL} as my shell
BLOCK1

类似地,你可以在Heredoc代码块内运行任何命令。

cat << BLOCK2
$(uname -a) 
BLOCK2

变量和命令替换

五、转义特殊字符

有几种方法可以转义特殊字符。你可以在字符级别或文档级别进行转义。

要转义单个特殊字符,请使用反斜杠 (\)

cat << BLOCK4
$(uname -a)
BLOCK4

cat << BLOCK5
Today date is = ${TODAY}
BLOCK5

要转义代码块内的所有特殊字符,请用单引号、双引号包围分隔符,或在分隔符前加反斜杠。

cat << 'BLOCK1'
I am running as = ${USER}
BLOCK1

cat << "BLOCK2"
I am running as = ${USER}
BLOCK2

cat << \BLOCK3
I am running as = ${USER}
BLOCK3

转义特殊字符

六、SSH批量命令

现在已经了解了Heredoc的结构和工作原理,最常用的场景是在通过SSH运行命令块和通过Heredoc传递SQL查询。

通过SSH运行命令

在下面的示例中,将一个select语句传递给psql,以连接到数据库并运行查询。这是在bash脚本中运行psql查询的一种替代方法,而不是使用-f标志来运行.sql文件。

#!/usr/bin/env bash

UNAME=postgres
DBNAME=testing

psql --username=${UNAME} --password --dbname=${DBNAME} << BLOCK
SELECT * FROM COUNTRIES
WHERE region_id = 4;
BLOCK

运行SQL查询

Heredoc除了可以适用上面SSH的批量命令的场景,还可以适用更多的场景如多行字符串处理,发布等等场景。

如何在Ubuntu 22.04/Ubuntu 20.04上安装OpenVPN
11 个Grep命令高级用法示例
标签:

发表我的评论

电子邮件地址不会被公开。 必填项已用*标注

66 + 15 =

ajax-loader