here document¶
备注
在很多shell场合中,我们需要根据模版来替换一些变量。我曾经做过很多次使用 sed
完成变量替换。但是, 私有云部署TLS认证的etcd集群 时,我突然意识到,实际上SHELL实际上早已内置了变量替换功能,只是我一直没有意识到(虽然已经使用过很多次),那就是 here document
。这里我来总结一下 here document
并说明如何使用这个变量替换。
什么是Here Document¶
Here Document
是Linux Shell 中的一种特殊的重定向方式,它的基本的形式如下:
cmd << delimiter
Here Document Content
delimiter
它的作用就是将两个 delimiter
(分隔符) 之间的内容(Here Document Content 部分) 传递给cmd 作为输入参数。比如在终端中输入 cat << EOF
,系统会提示继续进行输入,输入多行信息再输入EOF,中间输入的信息将会显示在屏幕上。
注意 :
EOF
只是一个标识而已,可以替换成任意的合法字符作为结尾的delimiter一定要顶格写,前面不能有任何字符
作为结尾的delimiter后面也不能有任何的字符(包括空格)
作为起始的delimiter前后的空格会被省略掉
Here Document 不仅可以在终端上使用,在shell 文件中也可以使用,例如下面的 here.sh
文件:
cat << EOF > output.sh
echo "hello"
echo "world"
EOF
使用 sh here.sh
运行这个脚本文件,会得到 output.sh
这个新文件,里面的内容如下:
echo "hello"
echo "world"
通常可以在一个shell脚本中采用上述方法生成新的脚本,这样就可以拆分脚本到多个子脚本进行不同的功能实现
delimiter 与变量¶
备注
关键点
来了
可以看到上文中我提到了采用 here document
来形成新的脚本,事实上我也经常这样做。但是,既然是脚本就会使用变量,那么我们把上面的那段 here.sh
脚本修改成使用变量会如何呢:
cat << EOF > output.sh
echo "This is output"
ehco $1
EOF
此时执行:
./here.sh HereDocument
则此时可以看到变量 $1
被展开,也就是最后形成的 output.sh
内容如下:
echo "This is output"
echo HereDocument
问题来了,如果我就是想最后生成的脚本 output.sh
是:
echo "This is output"
echo $1
该怎么搞呢?难道我运行 here.sh
脚本不传递参数就可以么?我们来试试 ./here.sh
,再看一下生成的 output.sh
脚本内容:
echo "This is output"
echo
哦,因为没有传递参数 $1
是空的,生成的新脚本 output.sh
展开了变量,只给我留下了一行 echo
。这不符合我的预想
如果不想展开变量 可以在 delimiter
的前后添加 "
来实现,也就是 here.sh
脚本修改成:
cat << "EOF" > output.sh #注意引号
echo "This is output"
echo $1
EOF
则再次执行 ./here.sh
,就会看到生成的 outpush.sh
脚本内容:
echo "This is output"
echo $1
备注
实际案例请参考 私有云部署TLS认证的etcd集群