📄 here-docs.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Here Documents</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Advanced Topics"HREF="part5.html"><LINKREL="PREVIOUS"TITLE="Globbing"HREF="globbingref.html"><LINKREL="NEXT"TITLE="I/O Redirection"HREF="io-redirection.html"><METAHTTP-EQUIV="Content-Style-Type"CONTENT="text/css"><LINKREL="stylesheet"HREF="common/kde-common.css"TYPE="text/css"><METAHTTP-EQUIV="Content-Type"CONTENT="text/html; charset=iso-8859-1"><METAHTTP-EQUIV="Content-Language"CONTENT="en"><LINKREL="stylesheet"HREF="common/kde-localised.css"TYPE="text/css"TITLE="KDE-English"><LINKREL="stylesheet"HREF="common/kde-default.css"TYPE="text/css"TITLE="KDE-Default"></HEAD><BODYCLASS="CHAPTER"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#AA0000"VLINK="#AA0055"ALINK="#AA0000"STYLE="font-family: sans-serif;"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="globbingref.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="io-redirection.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="HERE-DOCS"></A>Chapter 18. Here Documents</H1><TABLEBORDER="0"WIDTH="100%"CELLSPACING="0"CELLPADDING="0"CLASS="EPIGRAPH"><TR><TDWIDTH="45%"> </TD><TDWIDTH="45%"ALIGN="LEFT"VALIGN="TOP"><I><P><I>Here and now, boys.</I></P><P><I>--Aldous Huxley, <BCLASS="COMMAND">Island</B></I></P></I></TD></TR></TABLE><P><ANAME="HEREDOCREF"></A></P><P>A <ICLASS="FIRSTTERM">here document</I> is a special-purpose code block. It uses a form of <AHREF="io-redirection.html#IOREDIRREF">I/O redirection</A> to feed a command list to an interactive program or a command, such as <AHREF="communications.html#FTPREF">ftp</A>, <AHREF="external.html#CATREF">cat</A>, or the <ICLASS="FIRSTTERM">ex</I> text editor.</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 COMMAND <<InputComesFromHERE 2 ... 3 InputComesFromHERE</PRE></TD></TR></TABLE></P><P><ANAME="LIMITSTRINGREF"></A></P><P>A <ICLASS="FIRSTTERM">limit string</I> delineates (frames) the command list. The special symbol <SPANCLASS="TOKEN"><<</SPAN> designates the limit string. This has the effect of redirecting the output of a file into the <TTCLASS="FILENAME">stdin</TT> of the program or command. It is similar to <TTCLASS="USERINPUT"><B>interactive-program < command-file</B></TT>, where <TTCLASS="FILENAME">command-file</TT> contains <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 command #1 2 command #2 3 ...</PRE></TD></TR></TABLE></P><P>The <ICLASS="FIRSTTERM">here document</I> alternative looks like this:</P><P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 interactive-program <<LimitString 3 command #1 4 command #2 5 ... 6 LimitString</PRE></TD></TR></TABLE></P><P>Choose a <ICLASS="FIRSTTERM">limit string</I> sufficiently unusual that it will not occur anywhere in the command list and confuse matters.</P><P>Note that <ICLASS="FIRSTTERM">here documents</I> may sometimes be used to good effect with non-interactive utilities and commands, such as, for example, <AHREF="system.html#WALLREF">wall</A>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX70"></A><P><B>Example 18-1. <ICLASS="FIRSTTERM">broadcast</I>: Sends message to everyone logged in</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 wall <<zzz23EndOfMessagezzz23 4 E-mail your noontime orders for pizza to the system administrator. 5 (Add an extra dollar for anchovy or mushroom topping.) 6 # Additional message text goes here. 7 # Note: 'wall' prints comment lines. 8 zzz23EndOfMessagezzz23 9 10 # Could have been done more efficiently by 11 # wall <message-file 12 # However, embedding the message template in a script 13 #+ is a quick-and-dirty one-off solution. 14 15 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="VIHERE"></A></P><P>Even such unlikely candidates as the <ICLASS="FIRSTTERM">vi</I> text editor lend themselves to <ICLASS="FIRSTTERM">here documents</I>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX69"></A><P><B>Example 18-2. <ICLASS="FIRSTTERM">dummyfile</I>: Creates a 2-line dummy file</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # Non-interactive use of 'vi' to edit a file. 4 # Emulates 'sed'. 5 6 E_BADARGS=65 7 8 if [ -z "$1" ] 9 then 10 echo "Usage: `basename $0` filename" 11 exit $E_BADARGS 12 fi 13 14 TARGETFILE=$1 15 16 # Insert 2 lines in file, then save. 17 #--------Begin here document-----------# 18 vi $TARGETFILE <<x23LimitStringx23 19 i 20 This is line 1 of the example file. 21 This is line 2 of the example file. 22 ^[ 23 ZZ 24 x23LimitStringx23 25 #----------End here document-----------# 26 27 # Note that ^[ above is a literal escape 28 #+ typed by Control-V <Esc>. 29 30 # Bram Moolenaar points out that this may not work with 'vim', 31 #+ because of possible problems with terminal interaction. 32 33 exit 0</PRE></TD></TR></TABLE><HR></DIV><P> The above script could just as effectively have been implemented with <BCLASS="COMMAND">ex</B>, rather than <BCLASS="COMMAND">vi</B>. <ANAME="EXSCRIPTREF"></A><ICLASS="FIRSTTERM">Here documents</I> containing a list of <BCLASS="COMMAND">ex</B> commands are common enough to form their own category, known as <ICLASS="FIRSTTERM">ex scripts</I>. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # Replace all instances of "Smith" with "Jones" 3 #+ in files with a ".txt" filename suffix. 4 5 ORIGINAL=Smith 6 REPLACEMENT=Jones 7 8 for word in $(fgrep -l $ORIGINAL *.txt) 9 do 10 # ------------------------------------- 11 ex $word <<EOF 12 :%s/$ORIGINAL/$REPLACEMENT/g 13 :wq 14 EOF 15 # :%s is the "ex" substitution command. 16 # :wq is write-and-quit. 17 # ------------------------------------- 18 done</PRE></TD></TR></TABLE> </P><P><ANAME="CATSCRIPTREF"></A></P><P>Analogous to <SPANCLASS="QUOTE">"ex scripts"</SPAN> are <ICLASS="FIRSTTERM">cat scripts</I>.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX71"></A><P><B>Example 18-3. Multi-line message using <ICLASS="FIRSTTERM">cat</I></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # 'echo' is fine for printing single line messages, 4 #+ but somewhat problematic for for message blocks. 5 # A 'cat' here document overcomes this limitation. 6 7 cat <<End-of-message 8 ------------------------------------- 9 This is line 1 of the message. 10 This is line 2 of the message. 11 This is line 3 of the message. 12 This is line 4 of the message. 13 This is the last line of the message. 14 ------------------------------------- 15 End-of-message 16 17 # Replacing line 7, above, with 18 #+ cat > $Newfile <<End-of-message 19 #+ ^^^^^^^^^^ 20 #+ writes the output to the file $Newfile, rather than to stdout. 21 22 exit 0 23 24 25 #-------------------------------------------- 26 # Code below disabled, due to "exit 0" above. 27 28 # S.C. points out that the following also works. 29 echo "------------------------------------- 30 This is line 1 of the message. 31 This is line 2 of the message. 32 This is line 3 of the message. 33 This is line 4 of the message. 34 This is the last line of the message. 35 -------------------------------------" 36 # However, text may not include double quotes unless they are escaped.</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="LIMITSTRDASH"></A></P><P>The <TTCLASS="OPTION">-</TT> option to mark a here document limit string (<TTCLASS="USERINPUT"><B><<-LimitString</B></TT>) suppresses leading tabs (but not spaces) in the output. This may be useful in making a script more readable.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX71A"></A><P><B>Example 18-4. Multi-line message, with tabs suppressed</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # Same as previous example, but... 3 4 # The - option to a here document <<- 5 #+ suppresses leading tabs in the body of the document, 6 #+ but *not* spaces. 7 8 cat <<-ENDOFMESSAGE 9 This is line 1 of the message. 10 This is line 2 of the message. 11 This is line 3 of the message. 12 This is line 4 of the message. 13 This is the last line of the message. 14 ENDOFMESSAGE 15 # The output of the script will be flush left. 16 # Leading tab in each line will not show. 17 18 # Above 5 lines of "message" prefaced by a tab, not spaces. 19 # Spaces not affected by <<- . 20 21 # Note that this option has no effect on *embedded* tabs. 22 23 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="HEREPASSP"></A></P><P>A <ICLASS="FIRSTTERM">here document</I> supports parameter and command substitution. It is therefore possible to pass different parameters to the body of the here document, changing its output accordingly.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX71B"></A><P><B>Example 18-5. Here document with parameter substitution</B></P><TABLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -