📄 here-docs.html
字号:
29 30 echo "Listing of "$directory":"; echo 31 (printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n" \ 32 ; ls -l "$directory" | sed 1d) | column -t 33 34 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>Using a <AHREF="here-docs.html#CATSCRIPTREF">cat script</A> is an alternate way of accomplishing this.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 DOC_REQUEST=70 2 3 if [ "$1" = "-h" -o "$1" = "--help" ] # Request help. 4 then # Use a "cat script" . . . 5 cat <<DOCUMENTATIONXX 6 List the statistics of a specified directory in tabular format. 7 --------------------------------------------------------------- 8 The command line parameter gives the directory to be listed. 9 If no directory specified or directory specified cannot be read, 10 then list the current working directory. 11 12 DOCUMENTATIONXX 13 exit $DOC_REQUEST 14 fi</PRE></TD></TR></TABLE> </P><P>See also <AHREF="contributed-scripts.html#ISSPAMMER2">Example A-30</A> for one more excellent example of a self-documenting script.</P><P><ANAME="HERETEMP"></A></P><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>Here documents create temporary files, but these files are deleted after opening and are not accessible to any other process.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>bash -c 'lsof -a -p $$ -d0' << EOF</B></TT> <TTCLASS="PROMPT">> </TT><TTCLASS="USERINPUT"><B>EOF</B></TT> <TTCLASS="COMPUTEROUTPUT">lsof 1213 bozo 0r REG 3,5 0 30386 /tmp/t1213-0-sh (deleted)</TT> </PRE></TD></TR></TABLE> </P></TD></TR></TABLE></DIV><DIVCLASS="CAUTION"><TABLECLASS="CAUTION"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/caution.png"HSPACE="5"ALT="Caution"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>Some utilities will not work inside a <ICLASS="FIRSTTERM">here document</I>.</P></TD></TR></TABLE></DIV><P><ANAME="INDENTEDLS"></A></P><DIVCLASS="WARNING"><TABLECLASS="WARNING"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/warning.png"HSPACE="5"ALT="Warning"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>The closing <ICLASS="FIRSTTERM">limit string</I>, on the final line of a here document, must start in the <SPANCLASS="emphasis"><ICLASS="EMPHASIS">first</I></SPAN> character position. There can be <SPANCLASS="emphasis"><ICLASS="EMPHASIS">no leading whitespace</I></SPAN>. Trailing whitespace after the limit string likewise causes unexpected behavior. The whitespace prevents the limit string from being recognized.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 echo "----------------------------------------------------------------------" 4 5 cat <<LimitString 6 echo "This is line 1 of the message inside the here document." 7 echo "This is line 2 of the message inside the here document." 8 echo "This is the final line of the message inside the here document." 9 LimitString 10 #^^^^Indented limit string. Error! This script will not behave as expected. 11 12 echo "----------------------------------------------------------------------" 13 14 # These comments are outside the 'here document', 15 #+ and should not echo. 16 17 echo "Outside the here document." 18 19 exit 0 20 21 echo "This line had better not echo." # Follows an 'exit' command.</PRE></TD></TR></TABLE> </P></TD></TR></TABLE></DIV><P>For those tasks too complex for a <SPANCLASS="QUOTE">"here document"</SPAN>, consider using the <BCLASS="COMMAND">expect</B> scripting language, which is specifically tailored for feeding input into interactive programs.</P><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="AEN16438"></A>18.1. Here Strings</H1><P><ANAME="HERESTRINGSREF"></A></P><P>A <ICLASS="FIRSTTERM">here string</I> can be considered as a stripped-down form of a <ICLASS="FIRSTTERM">here document</I>. It consists of nothing more than <BCLASS="COMMAND">COMMAND <<<$WORD</B>, where <TTCLASS="VARNAME">$WORD</TT> is expanded and fed to the <TTCLASS="FILENAME">stdin</TT> of <TTCLASS="PARAMETER"><I>COMMAND</I></TT>.</P><P>As a simple example, consider this alternative to the <AHREF="internal.html#ECHOGREPREF">echo-grep</A> construction.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 # Instead of: 2 if echo "$VAR" | grep -q txt # if [[ $VAR = *txt* ]] 3 # etc. 4 5 # Try: 6 if grep -q "txt" <<< "$VAR" 7 then 8 echo "$VAR contains the substring sequence \"txt\"" 9 fi 10 # Thank you, Sebastian Kaminski, for the suggestion.</PRE></TD></TR></TABLE> </P><P><ANAME="HSREAD"></A></P><P>Or, in combination with <AHREF="internal.html#READREF">read</A>:</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 String="This is a string of words." 2 3 read -r -a Words <<< "$String" 4 # The -a option to "read" 5 #+ assigns the resulting values to successive members of an array. 6 7 echo "First word in String is: ${Words[0]}" # This 8 echo "Second word in String is: ${Words[1]}" # is 9 echo "Third word in String is: ${Words[2]}" # a 10 echo "Fourth word in String is: ${Words[3]}" # string 11 echo "Fifth word in String is: ${Words[4]}" # of 12 echo "Sixth word in String is: ${Words[5]}" # words. 13 echo "Seventh word in String is: ${Words[6]}" # (null) 14 # Past end of $String. 15 16 # Thank you, Francisco Lobo, for the suggestion.</PRE></TD></TR></TABLE> </P><P><ANAME="HSPRE"></A></P><DIVCLASS="EXAMPLE"><HR><ANAME="PREPENDEX"></A><P><B>Example 18-13. Prepending a line to a file</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # prepend.sh: Add text at beginning of file. 3 # 4 # Example contributed by Kenny Stauffer, 5 #+ and slightly modified by document author. 6 7 8 E_NOSUCHFILE=65 9 10 read -p "File: " file # -p arg to 'read' displays prompt. 11 if [ ! -e "$file" ] 12 then # Bail out if no such file. 13 echo "File $file not found." 14 exit $E_NOSUCHFILE 15 fi 16 17 read -p "Title: " title 18 cat - $file <<<$title > $file.new 19 20 echo "Modified file is $file.new" 21 22 exit 0 23 24 # from 'man bash': 25 # Here Strings 26 # A variant of here documents, the format is: 27 # 28 # <<<word 29 # 30 # The word is expanded and supplied to the command on its standard input.</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="MAILBOXGREP"></A><P><B>Example 18-14. Parsing a mailbox</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # Script by Francisco Lobo, 3 #+ and slightly modified and commented by ABS Guide author. 4 # Used in ABS Guide with permission. (Thank you!) 5 6 # This script will not run under Bash versions < 3.0. 7 8 9 E_MISSING_ARG=67 10 if [ -z "$1" ] 11 then 12 echo "Usage: $0 mailbox-file" 13 exit $E_MISSING_ARG 14 fi 15 16 mbox_grep() # Parse mailbox file. 17 { 18 declare -i body=0 match=0 19 declare -a date sender 20 declare mail header value 21 22 23 while IFS= read -r mail 24 # ^^^^ Reset $IFS. 25 # Otherwise "read" will strip leading & trailing space from its input. 26 27 do 28 if [[ $mail =~ "^From " ]] # Match "From" field in message. 29 then 30 (( body = 0 )) # "Zero out" variables. 31 (( match = 0 )) 32 unset date 33 34 elif (( body )) 35 then 36 (( match )) 37 # echo "$mail" 38 # Uncomment above line if you want entire body of message to display. 39 40 elif [[ $mail ]]; then 41 IFS=: read -r header value <<< "$mail" 42 # ^^^ "here string" 43 44 case "$header" in 45 [Ff][Rr][Oo][Mm] ) [[ $value =~ "$2" ]] && (( match++ )) ;; 46 # Match "From" line. 47 [Dd][Aa][Tt][Ee] ) read -r -a date <<< "$value" ;; 48 # ^^^ 49 # Match "Date" line. 50 [Rr][Ee][Cc][Ee][Ii][Vv][Ee][Dd] ) read -r -a sender <<< "$value" ;; 51 # ^^^ 52 # Match IP Address (may be spoofed). 53 esac 54 55 else 56 (( body++ )) 57 (( match )) && 58 echo "MESSAGE ${date:+of: ${date[*]} }" 59 # Entire $date array ^ 60 echo "IP address of sender: ${sender[1]}" 61 # Second field of "Received" line ^ 62 63 fi 64 65 66 done < "$1" # Redirect stdout of file into loop. 67 } 68 69 70 mbox_grep "$1" # Send mailbox file to function. 71 72 exit $? 73 74 # Exercises: 75 # --------- 76 # 1) Break the single function, above, into multiple functions, 77 #+ for the sake of readability. 78 # 2) Add additional parsing to the script, checking for various keywords. 79 80 81 82 $ mailbox_grep.sh scam_mail 83 MESSAGE of Thu, 5 Jan 2006 08:00:56 -0500 (EST) 84 IP address of sender: 196.3.62.4</PRE></TD></TR></TABLE><HR></DIV><P>Exercise: Find other uses for <ICLASS="FIRSTTERM">here strings</I>.</P></DIV></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="globbingref.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="io-redirection.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Globbing</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part5.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">I/O Redirection</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -