⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 here-docs.html

📁 BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版
💻 HTML
📖 第 1 页 / 共 2 页
字号:
  5&nbsp;RESPONDENT="the author of this fine script"    6&nbsp;  7&nbsp;cat &#60;&#60;'Endofmessage'  8&nbsp;  9&nbsp;Hello, there, $NAME. 10&nbsp;Greetings to you, $NAME, from $RESPONDENT. 11&nbsp; 12&nbsp;Endofmessage 13&nbsp; 14&nbsp;#  如果"limit string"被引用或转义的话, 那么就禁用了参数替换.  15&nbsp;#  下边的两种方式具有相同的效果.  16&nbsp;#  cat &#60;&#60;"Endofmessage" 17&nbsp;#  cat &#60;&#60;\Endofmessage 18&nbsp; 19&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>禁用了参数替换后, 将允许输出文本本身(译者注: 就是未转义的原文).         如果你想产生脚本甚至是程序代码的话, 那么可以使用这种办法. </P><DIVCLASS="EXAMPLE"><HR><ANAME="GENERATESCRIPT"></A><P><B>例子 17-8. 生成另外一个脚本的脚本</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# generate-script.sh  3&nbsp;# 这个脚本的诞生基于Albert Reiner的一个主意.   4&nbsp;  5&nbsp;OUTFILE=generated.sh         # 所产生文件的名字.   6&nbsp;  7&nbsp;  8&nbsp;# -----------------------------------------------------------  9&nbsp;# 'Here document包含了需要产生的脚本的代码.  10&nbsp;( 11&nbsp;cat &#60;&#60;'EOF' 12&nbsp;#!/bin/bash 13&nbsp; 14&nbsp;echo "This is a generated shell script." 15&nbsp;#  Note that since we are inside a subshell, 16&nbsp;#+ we can't access variables in the "outside" script. 17&nbsp; 18&nbsp;echo "Generated file will be named: $OUTFILE" 19&nbsp;#  Above line will not work as normally expected 20&nbsp;#+ because parameter expansion has been disabled. 21&nbsp;#  Instead, the result is literal output. 22&nbsp; 23&nbsp;a=7 24&nbsp;b=3 25&nbsp; 26&nbsp;let "c = $a * $b" 27&nbsp;echo "c = $c" 28&nbsp; 29&nbsp;exit 0 30&nbsp;EOF 31&nbsp;) &#62; $OUTFILE 32&nbsp;# ----------------------------------------------------------- 33&nbsp; 34&nbsp;#  将'limit string'引用起来将会阻止上边 35&nbsp;#+ here document消息体中的变量扩展.  36&nbsp;#  这会使得输出文件中的内容保持here document消息体中的原文.  37&nbsp; 38&nbsp;if [ -f "$OUTFILE" ] 39&nbsp;then 40&nbsp;  chmod 755 $OUTFILE 41&nbsp;  # 让所产生的文件具有可执行权限.  42&nbsp;else 43&nbsp;  echo "Problem in creating file: \"$OUTFILE\"" 44&nbsp;fi 45&nbsp; 46&nbsp;#  这个方法也可以用来产生 47&nbsp;#+ C程序代码, Perl程序代码, Python程序代码, makefile,  48&nbsp;#+ 和其他的一些类似的代码.  49&nbsp;#  (译者注: 中间一段没译的注释将会被here document打印出来) 50&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>        也可以将here document的输出保存到变量中. 	<TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;variable=$(cat &#60;&#60;SETVAR  2&nbsp;This variable  3&nbsp;runs over multiple lines.  4&nbsp;SETVAR)  5&nbsp;  6&nbsp;echo "$variable"</PRE></FONT></TD></TR></TABLE>      </P><P>A here document can supply input to a function in the same        script.</P><DIVCLASS="EXAMPLE"><HR><ANAME="HF"></A><P><B>例子 17-9. Here document与函数</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# here-function.sh  3&nbsp;  4&nbsp;GetPersonalData ()  5&nbsp;{  6&nbsp;  read firstname  7&nbsp;  read lastname  8&nbsp;  read address  9&nbsp;  read city  10&nbsp;  read state  11&nbsp;  read zipcode 12&nbsp;} # 这个函数看起来就是一个交互函数, 但是...  13&nbsp; 14&nbsp; 15&nbsp;# 给上边的函数提供输入. 16&nbsp;GetPersonalData &#60;&#60;RECORD001 17&nbsp;Bozo 18&nbsp;Bozeman 19&nbsp;2726 Nondescript Dr. 20&nbsp;Baltimore 21&nbsp;MD 22&nbsp;21226 23&nbsp;RECORD001 24&nbsp; 25&nbsp; 26&nbsp;echo 27&nbsp;echo "$firstname $lastname" 28&nbsp;echo "$address" 29&nbsp;echo "$city, $state $zipcode" 30&nbsp;echo 31&nbsp; 32&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P><ANAME="ANONHEREDOC0"></A></P><P>也可以这么使用<SPANCLASS="TOKEN">:</SPAN>(冒号), 			  做一个假命令来从一个here document中接收输出.         这么做事实上就是创建了一个<SPANCLASS="QUOTE">"匿名"</SPAN>的here document. 	</P><DIVCLASS="EXAMPLE"><HR><ANAME="ANONHEREDOC"></A><P><B>例子 17-10. <SPANCLASS="QUOTE">"匿名"</SPAN>的here Document</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;  3&nbsp;: &#60;&#60;TESTVARIABLES  4&nbsp;${HOSTNAME?}${USER?}${MAIL?}  # 如果其中某个变量没被设置, 那么就打印错误信息.   5&nbsp;TESTVARIABLES  6&nbsp;  7&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P><ANAME="CBLOCK1"></A></P><DIVCLASS="TIP"><P></P><TABLECLASS="TIP"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/tip.gif"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>上边所示技术的一种变化, 可以用来<SPANCLASS="QUOTE">"注释"</SPAN>掉代码块. </P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="COMMENTBLOCK"></A><P><B>例子 17-11. 注释掉一段代码块</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# commentblock.sh  3&nbsp;  4&nbsp;: &#60;&#60;COMMENTBLOCK  5&nbsp;echo "This line will not echo."  6&nbsp;This is a comment line missing the "#" prefix.  7&nbsp;This is another comment line missing the "#" prefix.  8&nbsp;  9&nbsp;&#38;*@!!++= 10&nbsp;The above line will cause no error message, 11&nbsp;because the Bash interpreter will ignore it. 12&nbsp;COMMENTBLOCK 13&nbsp; 14&nbsp;echo "Exit value of above \"COMMENTBLOCK\" is $?."   # 0 15&nbsp;# 这里将不会显示任何错误.  16&nbsp; 17&nbsp; 18&nbsp;#  上边的这种技术当然也可以用来注释掉 19&nbsp;#+ 一段正在使用的代码, 如果你有某些特定调试要求的话.  20&nbsp;#  这比在每行前边都敲入"#"来得方便的多,  21&nbsp;#+ 而且如果你想恢复的话, 还得将添加上的"#"删除掉.  22&nbsp; 23&nbsp;: &#60;&#60;DEBUGXXX 24&nbsp;for file in * 25&nbsp;do 26&nbsp; cat "$file" 27&nbsp;done 28&nbsp;DEBUGXXX 29&nbsp; 30&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><DIVCLASS="TIP"><P></P><TABLECLASS="TIP"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/tip.gif"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>关于这种小技巧的另一个应用就是能够产生<SPANCLASS="QUOTE">"自文档化(self-documenting)"</SPAN>的脚本. </P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="SELFDOCUMENT"></A><P><B>例子 17-12. 一个自文档化(self-documenting)的脚本</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# self-document.sh: 自文档化(self-documenting)的脚本  3&nbsp;# 修改于"colm.sh".  4&nbsp;  5&nbsp;DOC_REQUEST=70  6&nbsp;  7&nbsp;if [ "$1" = "-h"  -o "$1" = "--help" ]     # 请求帮助.   8&nbsp;then  9&nbsp;  echo; echo "Usage: $0 [directory-name]"; echo 10&nbsp;  sed --silent -e '/DOCUMENTATIONXX$/,/^DOCUMENTATIONXX$/p' "$0" | 11&nbsp;  sed -e '/DOCUMENTATIONXX$/d'; exit $DOC_REQUEST; fi 12&nbsp; 13&nbsp; 14&nbsp;: &#60;&#60;DOCUMENTATIONXX 15&nbsp;List the statistics of a specified directory in tabular format. 16&nbsp;--------------------------------------------------------------- 17&nbsp;The command line parameter gives the directory to be listed. 18&nbsp;If no directory specified or directory specified cannot be read, 19&nbsp;then list the current working directory. 20&nbsp; 21&nbsp;DOCUMENTATIONXX 22&nbsp; 23&nbsp;if [ -z "$1" -o ! -r "$1" ] 24&nbsp;then 25&nbsp;  directory=. 26&nbsp;else 27&nbsp;  directory="$1" 28&nbsp;fi   29&nbsp; 30&nbsp;echo "Listing of "$directory":"; echo 31&nbsp;(printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n" \ 32&nbsp;; ls -l "$directory" | sed 1d) | column -t 33&nbsp; 34&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>使用<AHREF="here-docs.html#CATSCRIPTREF">cat脚本</A>也能够完成相同的目的. </P><P>      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;DOC_REQUEST=70  2&nbsp;  3&nbsp;if [ "$1" = "-h"  -o "$1" = "--help" ]     # 请求帮助.   4&nbsp;then                                       # 使用"cat脚本" . . .   5&nbsp;  cat &#60;&#60;DOCUMENTATIONXX  6&nbsp;List the statistics of a specified directory in tabular format.  7&nbsp;---------------------------------------------------------------  8&nbsp;The command line parameter gives the directory to be listed.  9&nbsp;If no directory specified or directory specified cannot be read, 10&nbsp;then list the current working directory. 11&nbsp; 12&nbsp;DOCUMENTATIONXX 13&nbsp;exit $DOC_REQUEST 14&nbsp;fi</PRE></FONT></TD></TR></TABLE>      </P><P>请参考<AHREF="contributed-scripts.html#ISSPAMMER2">例子 A-28</A>可以看到更多关于<SPANCLASS="QUOTE">"自文档化"</SPAN>脚本的好例子. </P><DIVCLASS="NOTE"><P></P><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/note.gif"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>Here document创建临时文件, 			  但是这些文件将在打开后被删除, 			  并且不能够被任何其他进程所访问. 	    </P><P>	      <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">bash -c 'lsof -a -p $$ -d0' &#60;&#60; EOF</KBD><SAMPCLASS="PROMPT">&#62; </SAMP><KBDCLASS="USERINPUT">EOF</KBD><SAMPCLASS="COMPUTEROUTPUT">lsof    1213 bozo    0r   REG    3,5    0 30386 /tmp/t1213-0-sh (deleted)</SAMP>	      </PRE></FONT></TD></TR></TABLE>	  </P></TD></TR></TABLE></DIV><DIVCLASS="CAUTION"><P></P><TABLECLASS="CAUTION"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/caution.gif"HSPACE="5"ALT="Caution"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>某些工具是不能放入<EM>here document</EM>中运行的. </P></TD></TR></TABLE></DIV><P><ANAME="INDENTEDLS"></A></P><DIVCLASS="WARNING"><P></P><TABLECLASS="WARNING"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/warning.gif"HSPACE="5"ALT="Warning"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>结尾的<EM>limit string</EM>, 	  就是here document最后一行的limit string, 	  必须从<EM>第一个</EM>字符开始. 	  它的前面不能够有任何<EM>前置的空白</EM>. 	  而在这个limit string后边的空白也会引起异常. 	  空白将会阻止limit string的识别. 	  (译者注: 下边这个脚本由于结束limit string的问题, 	  造成脚本无法结束, 所有内容全部被打印出来, 	  所以注释就不译了, 保持这个例子脚本的原样.)  </P><P>	 <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;  3&nbsp;echo "----------------------------------------------------------------------"  4&nbsp;  5&nbsp;cat &#60;&#60;LimitString  6&nbsp;echo "This is line 1 of the message inside the here document."  7&nbsp;echo "This is line 2 of the message inside the here document."  8&nbsp;echo "This is the final line of the message inside the here document."  9&nbsp;     LimitString 10&nbsp;#^^^^Indented limit string. Error! This script will not behave as expected. 11&nbsp; 12&nbsp;echo "----------------------------------------------------------------------" 13&nbsp; 14&nbsp;#  These comments are outside the 'here document', 15&nbsp;#+ and should not echo. 16&nbsp; 17&nbsp;echo "Outside the here document." 18&nbsp; 19&nbsp;exit 0 20&nbsp; 21&nbsp;echo "This line had better not echo."  # Follows an 'exit' command.</PRE></FONT></TD></TR></TABLE>	 </P></TD></TR></TABLE></DIV><P>对于那些使用<SPANCLASS="QUOTE">"here document"</SPAN>, 并且非常复杂的任务, 		  最好考虑使用<BCLASS="COMMAND">expect</B>脚本语言, 		  这种语言就是为了达到向交互程序添加输入的目的而量身定做的. 	  </P></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="redirapps.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">首页</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="x13628.html"ACCESSKEY="N">下一页</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">重定向的应用</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part3.html"ACCESSKEY="U">上一级</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Here String</TD></TR></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -