here document 的一些技巧
here document 就是一段特殊目的的代码块. 他使用I/O 重定向的形式来将一个命令序列传递到一个交互程序或者命令中, 比如ftp, cat, 或者ex 文本编辑器.
3 InputComesFromHERE
limit string 用来划定命令序列的范围(译者注: 两个相同的limit string 之间就是命令序列) .
特殊符号 << 用来表识limit string. 这个符号具有重定向文件的输出到程序或命令的输入的作用.
与 interactive-program < command-file 很相象, command-file 包含:
1 command #1
2 command #2
3 …
而here document 的形式看上去是如下的样子:
2 interactive-program <
4 command #2
5 ...
6 LimitString
选择一个名字非常诡异的limit string 将会避免命令列表和limit string 重名的问题.
即使是某些不大可能的工具, 如vi 也可以使用here document.
1)使用vi创建一个文件,并写入内容
#!/bin/bash
# 用非交互的方式来使用'vi'编辑一个文件.
# 模仿'sed'.
E_BADARGS=65
if [ -z “$1″ ]
then
echo “Usage: `basename $0` filename”
exit $E_BADARGS
fi
TARGETFILE=$1
# 在文件中插入两行, 然后保存.
#——–Begin here document———–#
/bin/vi $TARGETFILE <
This is line 1 of the example file.
This is line 2 of the example file.
ZZ
x23LimitStringx23
#----------End here document-----------#
# 注意上边^[是一个转义符,键入Ctrl+v
#+ 事实上它是
# Bram Moolenaar 指出这种方法不能正常地用在'vim'上, ( Bram Moolenaar 是vim 作者),
#+ 因此这里使用了/bin/vi而不是vim,直接输入vi,调用的可能是vim,可以看看你的alias列表中是#+否 有vi的定义
exit 0
Vim: Warning: Input is not from a terminal
[root@lancy bin]# cat one
This is line 1 of the example file.
This is line 2 of the example file.
2)多行消息输出
使用echo来打印单行消息非常有用,但是在打印消息块的时候就麻烦了一点,这个时候我们可以使用cat here document的的方式来解决
cat <
this is line 2
this is line 3
EndMsg
exit 0
这样可以打印上面的三行信息,用tab键退后是为了代码好看,但是带来的影响是tab键也将被输出,这可能不是我们所期望的,我们可以使用-here document 来解决,看看下面的例子
cat <<-EndMsg
this is line 1
this is line 2
this is line 3
EndMsg
exit 0
看看打印的结果有什么不同?
3)参数替换
here document 支持参数和命令替换. 所以也可以给here document 的消息体传递不同的参数,
这样相应的也会修改输出.
看下面的代码
NAME=${1:-”Mr. smith”}
cat <
Greetings to you,$NAME
#this comment shows up in the output
EndMsg
exit 0
4)禁止参数替换
在here document 的开头引用或转义”limit string”会使得here document 的消息体中的参数替
换被禁用.这在需要某些原始输出时很有用。
再看下面的代码,看看输出和上面的有什么不同
NAME=${1:-”Mr. smith”}
cat <<'EndMsg'
hello,there,$NAME
Greetings to you,$NAME
#this comment shows up in the output
EndMsg
exit 0
下面的两种情况类似
cat <<\EndMsg
禁用了参数替换后, 将允许输出文本本身. 产生脚本甚至是程序 代码就是这种用法的用途之一.
5)here document与函数
同一脚本中的函数也可以接受here document 的输出作为自身的参数.看下面的代码
printsomething()
{
read one
read two
read three
echo “the value arg 1 is $one”
}
#上面这个函数无疑是一个交互性的函数,但是我们可以做调用
printsomething <
this is two
this is three
EndMsg
exit 0
5)匿名 here document
做一个假命令来从一个here document 中接收输出. 这么做事实上就是创建了
一个”匿名”的here document.
看看下面的代码
: <
TESTVARIABLES
exit 0
上边的这种技术当然也可以用来注释掉一段正在使用的代码, 如果你有某些特定调试要求的话
这将比对每行都敲入”#”来得方便的多, 而且如果你想恢复的话, 还得将添加上的”#”删除掉.
看下面的代码
: <
do
cat $i
done
DebugIt
exit 0
这样这段for循环代码就注释了,下次要使用,只需要删除:<
# self-document.sh: 自文档化(self-documenting)的脚本
# Modification of “colm.sh”.
DOC_REQUEST=70
if [ “$1″ = “-h” -o “$1″ = “–help” ] # 请求帮助.
then
echo; echo “Usage: $0 [directory-name]”; echo
sed –silent -e '/DOCUMENTATIONXX$/,/^DOCUMENTATIONXX$/p' “$0″ |
sed -e '/DOCUMENTATIONXX$/d'; exit $DOC_REQUEST; fi
: <
---------------------------------------------------------------
The command line parameter gives the directory to be listed.
If no directory specified or directory specified cannot be read,
then list the current working directory.
DOCUMENTATIONXX
if [ -z "$1" -o ! -r "$1" ]
then
directory=.
else
directory="$1"
fi
echo "Listing of "$directory":"; echo
(printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n" \
; ls -l "$directory" | sed 1d) | column -t
exit 0
注意: Here document 创建临时文件, 但是这些文件将在打开后被删除, 并且不能够被任何其
他进程所存取.
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
lsof 6238 root 0r REG 3,5 0 212880 /tmp/sh-thd-1158429626 (deleted)
警告: 结束的limit string, 就是here document 最后一行的limit string, 必须开始于第一
个字符位置. 它的前面不能够有任何前置的空白. 而在这个limit string 后边的空白也会
引起异常问题. 空白将会阻止limit string 的识别.
(以上部分内容来自ABS一书)
原创文章,转载请注明: 转载自Linux|系统管理|WEB开发
本文链接地址: here document 的一些技巧




近期评论