19. 嵌入文档

Here and now, boys.     --Aldous Huxley, Island

嵌入文档是一段有特殊作用的代码块,它用 I/O 重定向 在交互程序和交互命令中传递和反馈一个命令列表,例如 ftpcat 或者是 ex 文本编辑器

COMMAND <<InputComesFromHERE
...
...
...
InputComesFromHERE

嵌入文档用限定符作为命令列表的边界,在限定符前需要一个指定的标识符 <<,这会将一个程序或命令的标准输入(stdin)进行重定向,它类似 交互程序 < 命令文件 的方式,其中命令文件内容如下

command #1
command #2
...

嵌入文档的格式大致如下

interactive-program <<LimitString
command #1
command #2
...
LimitString

限定符的选择必须保证特殊以确保不会和命令列表里的内容发生混淆。

注意嵌入文档有时候用作非交互的工具和命令有着非常好的效果,例如 wall

样例 19-1. broadcast: 给每个登陆者发送信息

样例: 19-2. dummyfile:创建一个有两行内容的虚拟文件

上述脚本实现了 ex 的功能, 而不是 vi. 嵌入文档包含了 ex 足够通用的命令列表来形成自有的类别, 所以又称之为 ex 脚本.

类似的 ex 脚本cat 脚本.

样例 19-3. 使用 cat 的多行信息

- 的作用是标记了一个嵌入文档限制符 (<<-LimitString) ,它能抑制输出的行首的 tab (非空格). 这在脚本可读性方面可能非常有用.

样例 19-4. 抑制 tab 的多行信息

嵌入文档支持参数和命令替换. 因此可以向嵌入文档传递不同的参数,变向的改其输出.

样例 19-5. 可替换参数的嵌入文档

这个包含参数替换的嵌入文档是相当有用的

样例 19-6. 上传文件对到 Sunsite 入口目录

在嵌入文档头部引用或转义"限制符"来禁用参数替换.原因是 引用/转义 限定符能有效的转义 "$", "`", 和 "\" 这些特殊符号, 使他们维持字面上的意思. (感谢 Allen Halsey 指出这点.)

样例 19-7. 禁用参数替换

生成脚本或者程序代码时可以用禁用参数的方式来输出文本.

样例 19-8. 生成其他脚本的脚本

可以从嵌入文档的输出设置一个变量的值. 这实际上是种灵活的 命令替换.

同样的脚本里嵌入文档可以作为函数的输入.

样例 19-9. 嵌入文档和函数

可以这样使用: 作为一个虚构的命令接受嵌入文档的输出. 这样实际上就创建了一个 "匿名" 嵌入文档.

样例 19-10. "匿名" 嵌入文档

  • 上面技巧的一种变体允许 "可添加注释" 的代码块.

样例 19-11. 可添加注释的代码块

  • 另一个漂亮的方法使得"自文档化"的脚本成为可能

样例 19-12. 自文档化的脚本

使用 cat script 是另一种可行的方法.

另请参阅 样例 A-28, 样例 A-40, 样例 A-41, and 样例 A-42 更多样例请阅读脚本附带的注释文档.

  • 嵌入文档创建了临时文件, 但这些文件在打开且不可被其他程序访问后删除.

  • 某些工具在嵌入文档内部并不能正常运行.

  • 在嵌入文档的最后关闭限定符必须在起始的第一个字符的位置开始.行首不能是空格. 限制符后尾随空格同样会导致意想不到的行为.空格可以防止限制符被当做其他用途. [1]

  • 有些人非常聪明的使用了一个单引号(!)做为限制符. 但这并不是个好主意

为嵌入文档设置这些任务有些复杂, 可以考虑使用 expect, 一种专门用来和程序进行交互的脚本语言。

Notes:   除此之外, Dennis Benzinger 指出, 使用 <<- 抑制 tab.

Last updated

Was this helpful?