📄 here-docs.html
字号:
BORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # Another 'cat' here document, using parameter substitution. 3 4 # Try it with no command line parameters, ./scriptname 5 # Try it with one command line parameter, ./scriptname Mortimer 6 # Try it with one two-word quoted command line parameter, 7 # ./scriptname "Mortimer Jones" 8 9 CMDLINEPARAM=1 # Expect at least command line parameter. 10 11 if [ $# -ge $CMDLINEPARAM ] 12 then 13 NAME=$1 # If more than one command line param, 14 #+ then just take the first. 15 else 16 NAME="John Doe" # Default, if no command line parameter. 17 fi 18 19 RESPONDENT="the author of this fine script" 20 21 22 cat <<Endofmessage 23 24 Hello, there, $NAME. 25 Greetings to you, $NAME, from $RESPONDENT. 26 27 # This comment shows up in the output (why?). 28 29 Endofmessage 30 31 # Note that the blank lines show up in the output. 32 # So does the "comment". 33 34 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="HEREPARAMSUB"></A></P><P>This is a useful script containing a here document with parameter substitution.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX72"></A><P><B>Example 18-6. Upload a file pair to <ICLASS="FIRSTTERM">Sunsite</I> incoming directory</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # upload.sh 3 4 # Upload file pair (Filename.lsm, Filename.tar.gz) 5 #+ to incoming directory at Sunsite/UNC (ibiblio.org). 6 # Filename.tar.gz is the tarball itself. 7 # Filename.lsm is the descriptor file. 8 # Sunsite requires "lsm" file, otherwise will bounce contributions. 9 10 11 E_ARGERROR=65 12 13 if [ -z "$1" ] 14 then 15 echo "Usage: `basename $0` Filename-to-upload" 16 exit $E_ARGERROR 17 fi 18 19 20 Filename=`basename $1` # Strips pathname out of file name. 21 22 Server="ibiblio.org" 23 Directory="/incoming/Linux" 24 # These need not be hard-coded into script, 25 #+ but may instead be changed to command line argument. 26 27 Password="your.e-mail.address" # Change above to suit. 28 29 ftp -n $Server <<End-Of-Session 30 # -n option disables auto-logon 31 32 user anonymous "$Password" 33 binary 34 bell # Ring 'bell' after each file transfer. 35 cd $Directory 36 put "$Filename.lsm" 37 put "$Filename.tar.gz" 38 bye 39 End-Of-Session 40 41 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="HEREESC"></A></P><P>Quoting or escaping the <SPANCLASS="QUOTE">"limit string"</SPAN> at the head of a here document disables parameter substitution within its body.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX71C"></A><P><B>Example 18-7. Parameter substitution turned off</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # A 'cat' here-document, but with parameter substitution disabled. 3 4 NAME="John Doe" 5 RESPONDENT="the author of this fine script" 6 7 cat <<'Endofmessage' 8 9 Hello, there, $NAME. 10 Greetings to you, $NAME, from $RESPONDENT. 11 12 Endofmessage 13 14 # No parameter substitution when the "limit string" is quoted or escaped. 15 # Either of the following at the head of the here document would have 16 #+ the same effect. 17 # cat <<"Endofmessage" 18 # cat <<\Endofmessage 19 20 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="HERELIT"></A></P><P>Disabling parameter substitution permits outputting literal text. Generating scripts or even program code is one use for this.</P><DIVCLASS="EXAMPLE"><HR><ANAME="GENERATESCRIPT"></A><P><B>Example 18-8. A script that generates another script</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # generate-script.sh 3 # Based on an idea by Albert Reiner. 4 5 OUTFILE=generated.sh # Name of the file to generate. 6 7 8 # ----------------------------------------------------------- 9 # 'Here document containing the body of the generated script. 10 ( 11 cat <<'EOF' 12 #!/bin/bash 13 14 echo "This is a generated shell script." 15 # Note that since we are inside a subshell, 16 #+ we can't access variables in the "outside" script. 17 18 echo "Generated file will be named: $OUTFILE" 19 # Above line will not work as normally expected 20 #+ because parameter expansion has been disabled. 21 # Instead, the result is literal output. 22 23 a=7 24 b=3 25 26 let "c = $a * $b" 27 echo "c = $c" 28 29 exit 0 30 EOF 31 ) > $OUTFILE 32 # ----------------------------------------------------------- 33 34 # Quoting the 'limit string' prevents variable expansion 35 #+ within the body of the above 'here document.' 36 # This permits outputting literal strings in the output file. 37 38 if [ -f "$OUTFILE" ] 39 then 40 chmod 755 $OUTFILE 41 # Make the generated file executable. 42 else 43 echo "Problem in creating file: \"$OUTFILE\"" 44 fi 45 46 # This method can also be used for generating 47 #+ C programs, Perl programs, Python programs, Makefiles, 48 #+ and the like. 49 50 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="HERECS"></A></P><P> It is possible to set a variable from the output of a here document. This is actually a devious form of <AHREF="commandsub.html#COMMANDSUBREF">command substitution</A>. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 variable=$(cat <<SETVAR 2 This variable 3 runs over multiple lines. 4 SETVAR) 5 6 echo "$variable"</PRE></TD></TR></TABLE> </P><P><ANAME="HEREFUNC"></A></P><P>A here document can supply input to a function in the same script.</P><DIVCLASS="EXAMPLE"><HR><ANAME="HF"></A><P><B>Example 18-9. Here documents and functions</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # here-function.sh 3 4 GetPersonalData () 5 { 6 read firstname 7 read lastname 8 read address 9 read city 10 read state 11 read zipcode 12 } # This certainly looks like an interactive function, but... 13 14 15 # Supply input to the above function. 16 GetPersonalData <<RECORD001 17 Bozo 18 Bozeman 19 2726 Nondescript Dr. 20 Baltimore 21 MD 22 21226 23 RECORD001 24 25 26 echo 27 echo "$firstname $lastname" 28 echo "$address" 29 echo "$city, $state $zipcode" 30 echo 31 32 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="ANONHEREDOC0"></A></P><P>It is possible to use <SPANCLASS="TOKEN">:</SPAN> as a dummy command accepting output from a here document. This, in effect, creates an <SPANCLASS="QUOTE">"anonymous"</SPAN> here document.</P><DIVCLASS="EXAMPLE"><HR><ANAME="ANONHEREDOC"></A><P><B>Example 18-10. <SPANCLASS="QUOTE">"Anonymous"</SPAN> Here Document</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 : <<TESTVARIABLES 4 ${HOSTNAME?}${USER?}${MAIL?} # Print error message if one of the variables not set. 5 TESTVARIABLES 6 7 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="CBLOCK1"></A></P><DIVCLASS="TIP"><TABLECLASS="TIP"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/tip.png"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>A variation of the above technique permits <SPANCLASS="QUOTE">"commenting out"</SPAN> blocks of code.</P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="COMMENTBLOCK"></A><P><B>Example 18-11. Commenting out a block of code</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # commentblock.sh 3 4 : <<COMMENTBLOCK 5 echo "This line will not echo." 6 This is a comment line missing the "#" prefix. 7 This is another comment line missing the "#" prefix. 8 9 &*@!!++= 10 The above line will cause no error message, 11 because the Bash interpreter will ignore it. 12 COMMENTBLOCK 13 14 echo "Exit value of above \"COMMENTBLOCK\" is $?." # 0 15 # No error shown. 16 echo 17 18 19 # The above technique also comes in useful for commenting out 20 #+ a block of working code for debugging purposes. 21 # This saves having to put a "#" at the beginning of each line, 22 #+ then having to go back and delete each "#" later. 23 24 echo "Just before commented-out code block." 25 # The lines of code between the double-dashed lines will not execute. 26 # =================================================================== 27 : <<DEBUGXXX 28 for file in * 29 do 30 cat "$file" 31 done 32 DEBUGXXX 33 # =================================================================== 34 echo "Just after commented-out code block." 35 36 exit 0 37 38 39 40 ###################################################################### 41 # Note, however, that if a bracketed variable is contained within 42 #+ the commented-out code block, 43 #+ then this could cause problems. 44 # for example: 45 46 47 #/!/bin/bash 48 49 : <<COMMENTBLOCK 50 echo "This line will not echo." 51 &*@!!++= 52 ${foo_bar_bazz?} 53 $(rm -rf /tmp/foobar/) 54 $(touch my_build_directory/cups/Makefile) 55 COMMENTBLOCK 56 57 58 $ sh commented-bad.sh 59 commented-bad.sh: line 3: foo_bar_bazz: parameter null or not set 60 61 # The remedy for this is to strong-quote the 'COMMENTBLOCK' in line 49, above. 62 63 : <<'COMMENTBLOCK' 64 65 # Thank you, Kurt Pfeifle, for pointing this out.</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="HSELFDOC"></A></P><DIVCLASS="TIP"><TABLECLASS="TIP"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/tip.png"HSPACE="5"ALT="Tip"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>Yet another twist of this nifty trick makes <SPANCLASS="QUOTE">"self-documenting"</SPAN> scripts possible.</P></TD></TR></TABLE></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="SELFDOCUMENT"></A><P><B>Example 18-12. A self-documenting script</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # self-document.sh: self-documenting script 3 # Modification of "colm.sh". 4 5 DOC_REQUEST=70 6 7 if [ "$1" = "-h" -o "$1" = "--help" ] # Request help. 8 then 9 echo; echo "Usage: $0 [directory-name]"; echo 10 sed --silent -e '/DOCUMENTATIONXX$/,/^DOCUMENTATIONXX$/p' "$0" | 11 sed -e '/DOCUMENTATIONXX$/d'; exit $DOC_REQUEST; fi 12 13 14 : <<DOCUMENTATIONXX 15 List the statistics of a specified directory in tabular format. 16 --------------------------------------------------------------- 17 The command line parameter gives the directory to be listed. 18 If no directory specified or directory specified cannot be read, 19 then list the current working directory. 20 21 DOCUMENTATIONXX 22 23 if [ -z "$1" -o ! -r "$1" ] 24 then 25 directory=. 26 else 27 directory="$1" 28 fi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -