Shell 还有一种特殊形式的重定向叫做“Here Document”,目前没有统一的翻译,你可以将它理解为“嵌入文档”“内嵌文档”“立即文档”。
所谓文档,就是命令需要处理的数据或者字符串;所谓嵌入,就是把数据和代码放在一起,而不是分开存放(比如将数据放在一个单独的文件中)。有时候命令需要处理的数据量很小,将它放在一个单独的文件中有点“大动干戈”,不如直接放在代码中来得方便。
Here Document 的基本用法为:
command是 Shell 命令,<<END是开始标志,END是结束标志,document是输入的文档(也就是一行一行的字符串)。
这种写法告诉 Shell 把 document 部分作为命令需要处理的数据,直到遇见终止符END为止(终止符END不会被读取)。
注意,终止符END必须独占一行,并且要定顶格写。
分界符(终止符)可以是任意的字符串,由用户自己定义,比如 END、MARKER 等。分界符可以出现在正常的数据流中,只要它不是顶格写的独立的一行,就不会被作为结束标志。
【实例1】cat 命令一般是从文件中读取内容,并将内容输出到显示器上,借助 Here Document,cat 命令可以从键盘上读取内容。
[mozhiyan@localhost ~]$ cat <<END > Shell教程 > http://www.cdsy.xyz/computer/programme/shell/ > 已经进行了三次改版 > END Shell教程 http://www.cdsy.xyz/computer/programme/shell/ 已经进行了三次改版
<是第二层命令提示符。
正文中也可以出现结束标志END,只要它不是独立的一行,并且不顶格写,就没问题。
[mozhiyan@localhost ~]$ cat <<END > END可以出现在行首 > 出现在行尾的END > 出现在中间的END也是允许的 > END END可以出现在行首 出现在行尾的END 出现在中间的END也是允许的
【实例2】在脚本文件中使用 Here Document,并将 document 中的内容转换为大写。
#!/bin/bash
#在脚本文件中使用立即文档
tr a-z A-Z <<END
one two three
Here Document
END
将代码保存到 test.sh 并运行,结果为:
ONE TWO THREE
HERE DOCUMENT
默认情况下,正文中出现的变量和命令也会被求值或运行,Shell 会先将它们替换以后再交给 command,请看下面的例子:
[mozhiyan@localhost ~]$ name=城东书院 [mozhiyan@localhost ~]$ url=http://www.cdsy.xyz [mozhiyan@localhost ~]$ age=2 [mozhiyan@localhost ~]$ cat <<END > ${name}已经${age}岁了,它的网址是 ${url} > END 城东书院已经7岁了,它的网址是 http://www.cdsy.xyz
你可以将分界符用单引号或者双引号包围起来使 Shell 替换失效:
[mozhiyan@localhost ~]$ name=城东书院 [mozhiyan@localhost ~]$ url=http://www.cdsy.xyz [mozhiyan@localhost ~]$ age=2 [mozhiyan@localhost ~]$ cat <<'END' #使用单引号包围 > ${name}已经${age}岁了,它的网址是 ${url} > END ${name}已经${age}岁了,它的网址是 ${url}
默认情况下,行首的制表符也被当做正文的一部分。
#!/bin/bash
cat <<END
Shell教程
http://www.cdsy.xyz/computer/programme/shell/
已经进行了三次改版
END
将代码保存到 test.sh 并运行,结果如下:
Shell教程
http://www.cdsy.xyz/computer/programme/shell/
已经进行了三次改版
这里的制表符仅仅是为了格式对齐,我们并不希望它作为正文的一部分,为了达到这个目的,你可以在<<和END之间增加-,请看下面的代码:
#!/bin/bash
#增加了减号-
cat <<-END
Shell教程
http://www.cdsy.xyz/computer/programme/shell/
已经进行了三次改版
END
这次的运行结果为:
Shell教程
http://www.cdsy.xyz/computer/programme/shell/
已经进行了三次改版
如果你尝试在脚本嵌入一小块多行数据,使用 Here Document 是很有用的,而嵌入很大的数据块是一个不好的习惯。你应该保持你的逻辑(你的代码)和你的输入(你的数据)分离,最好是在不同的文件中,除非是输入一个很小的数据集。
Here Document 最常用的功能还是向用户显示命令或者脚本的用法信息,例如类似下面的函数:
usage(){
cat <<-END
usage: command [-x] [-v] [-z] [file ...]
A short explanation of the operation goes here.
It might be a few lines long, but shouldn't be excessive.
END
}