Here Documents
有一种特别的方式通过输入从而到达一个shell脚本的指令中,这种方式就是使用here document。它允许一个实际上输入是来自于脚本的命令去执行,就好像是从一个文件或者键盘所读取的那样。
一个here document由前导字符<<开始,之后跟随一个在文档结尾不断重复的特殊字符序列。<<是shell下的重定向标签,在此情况下,它会强迫命令将输入给here document。这个特殊序列就像一个标记一样,用来告诉shell哪里是here document的结尾。这个标记序列绝对不可以出现在要传递给命令的行上,因此最好是将他们标记为令人难为的或最不常用的的内容.
下面是一个最简单的将输入给cat指令的示例:
#!/bin/sh
cat <<!FUNKY!
hello
this is a here document
!FUNKY!
结果如下显示:
hellothis is a here document
here document看上去也许是一个古怪的特征,但是它的确是非常的强大,因为它能够让我们调用一个交互的程序,比如一个编辑器,同时给这个程序一些预先确定的输入。不过,正如我们先前所看到的那样,它们一般通常都用于从一个脚本的内部输出大量的文本,从而避免每一行都不得不使用echo指令来输出。另外,我们在每一行的标记符都使用了!来标记,以确保不会造成迷惑。
如果我们想要以实现确定的方式来处理文件中的一些行的话,可以通过使用行编辑器ed在一个Shell脚本中使用here document提供相关的命令。示例如下:
1.假设有一个文件a_txt_file,内容如下:
That is line 1That is line 2
That is line 3
That is line 4
2.我们通过一个here document组合和ed编辑器来编辑此文件:
#!/bin/sh
ed a_text_file <<!FunkyStuff!
3
d
.,\$s/is/was/
w
q
!FunkyStuff!
exit 0
如果运行上面的脚本,将输出如下结果:
That is line 1That is line 2
That was line 4
工作原理:
这个Shell脚本只是简单的调用了ed编辑器,然后将一些要执行的动作命令传递给ed编辑器,这些命令分别是移动到第三行、删除此行以及在当前行用was来替换is。这些ed命令都是从构成here document的脚本中的所有行所构成的,也就是在!FunkyStuff!之间的部分.
注意:
上例在here document中\只是防止shell将$当作shell扩展,即\将$给转义了,这样shell就不会扩展$s/is/was来获取它的值,当然它原本就没有什么值。相反,shell所跳过的被当作$的文本\$,在之后会由ed编辑器来解释,从而得到相关的意思。