Shell Here Document(内嵌文档/嵌入文档)
Shell 还有一种特殊形式的重定向叫做“Here Document”,目前没有统一的翻译,你可以将它理解为“嵌入文档”“内嵌文档”“立即文档”。
所谓文档,就是命令需要处理的数据或者字符串;所谓嵌入,就是把数据和代码放在一起,而不是分开存放(比如将数据放在一个单独的文件中)。有时候命令需要处理的数据量很小,将它放在一个单独的文件中有点“大动干戈”,不如直接放在代码中来得方便。
Here Document 的基本用法为:
这种写法告诉 Shell 把 document 部分作为命令需要处理的数据,直到遇见终止符
注意,终止符
分界符(终止符)可以是任意的字符串,由用户自己定义,比如 END、MARKER 等。分界符可以出现在正常的数据流中,只要它不是顶格写的独立的一行,就不会被作为结束标志。
【实例1】cat 命令一般是从文件中读取内容,并将内容输出到显示器上,借助 Here Document,cat 命令可以从键盘上读取内容。
正文中也可以出现结束标志
【实例2】在脚本文件中使用 Here Document,并将 document 中的内容转换为大写。
ONE TWO THREE
HERE DOCUMENT
你可以将分界符用单引号或者双引号包围起来使 Shell 替换失效:
Shell教程
https://www.xinbaoku.com/shell/
已经进行了三次改版
这里的制表符仅仅是为了格式对齐,我们并不希望它作为正文的一部分,为了达到这个目的,你可以在
Shell教程
https://www.xinbaoku.com/shell/
已经进行了三次改版
Here Document 最常用的功能还是向用户显示命令或者脚本的用法信息,例如类似下面的函数:
所谓文档,就是命令需要处理的数据或者字符串;所谓嵌入,就是把数据和代码放在一起,而不是分开存放(比如将数据放在一个单独的文件中)。有时候命令需要处理的数据量很小,将它放在一个单独的文件中有点“大动干戈”,不如直接放在代码中来得方便。
Here Document 的基本用法为:
command <<END
document
END
command
是 Shell 命令,<<END
是开始标志,END
是结束标志,document
是输入的文档(也就是一行一行的字符串)。这种写法告诉 Shell 把 document 部分作为命令需要处理的数据,直到遇见终止符
END
为止(终止符END
不会被读取)。注意,终止符
END
必须独占一行,并且要定顶格写。分界符(终止符)可以是任意的字符串,由用户自己定义,比如 END、MARKER 等。分界符可以出现在正常的数据流中,只要它不是顶格写的独立的一行,就不会被作为结束标志。
【实例1】cat 命令一般是从文件中读取内容,并将内容输出到显示器上,借助 Here Document,cat 命令可以从键盘上读取内容。
[mozhiyan@localhost ~]$ cat <<END > Shell教程 > https://www.xinbaoku.com/shell/ > 已经进行了三次改版 > END Shell教程 https://www.xinbaoku.com/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=https://www.xinbaoku.com [mozhiyan@localhost ~]$ age=7 [mozhiyan@localhost ~]$ cat <<END > ${name}已经${age}岁了,它的网址是 ${url} > END 新宝库已经7岁了,它的网址是 https://www.xinbaoku.com
你可以将分界符用单引号或者双引号包围起来使 Shell 替换失效:
[mozhiyan@localhost ~]$ name=新宝库 [mozhiyan@localhost ~]$ url=https://www.xinbaoku.com [mozhiyan@localhost ~]$ age=7 [mozhiyan@localhost ~]$ cat <<'END' #使用单引号包围 > ${name}已经${age}岁了,它的网址是 ${url} > END ${name}已经${age}岁了,它的网址是 ${url}
忽略制表符
默认情况下,行首的制表符也被当做正文的一部分。#!/bin/bash cat <<END Shell教程 https://www.xinbaoku.com/shell/ 已经进行了三次改版 END将代码保存到 test.sh 并运行,结果如下:
Shell教程
https://www.xinbaoku.com/shell/
已经进行了三次改版
这里的制表符仅仅是为了格式对齐,我们并不希望它作为正文的一部分,为了达到这个目的,你可以在
<<
和END
之间增加-
,请看下面的代码:
#!/bin/bash #增加了减号- cat <<-END Shell教程 https://www.xinbaoku.com/shell/ 已经进行了三次改版 END这次的运行结果为:
Shell教程
https://www.xinbaoku.com/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 }
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算