📄 bash2.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Bash, versions 2 and 3</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="Shell Scripting Under Windows"HREF="winscript.html"><LINKREL="NEXT"TITLE="Bash, version 3"HREF="bashver3.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="winscript.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="bashver3.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="BASH2"></A>Chapter 34. Bash, versions 2 and 3</H1><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="BASHVER2"></A>34.1. Bash, version 2</H1><P><ANAME="BASH2REF"></A></P><P>The current version of <ICLASS="FIRSTTERM">Bash</I>, the one you have running on your machine, is version 2.xx.y or 3.xx.y. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>echo $BASH_VERSION</B></TT> <TTCLASS="COMPUTEROUTPUT">3.2.25(1)-release</TT> </PRE></TD></TR></TABLE> The version 2 update of the classic Bash scripting language added array variables, <ANAME="AEN19239"HREF="#FTN.AEN19239">[1]</A> string and parameter expansion, and a better method of indirect variable references, among other features.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX77"></A><P><B>Example 34-1. String expansion</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # String expansion. 4 # Introduced with version 2 of Bash. 5 6 # Strings of the form $'xxx' 7 #+ have the standard escaped characters interpreted. 8 9 echo $'Ringing bell 3 times \a \a \a' 10 # May only ring once with certain terminals. 11 echo $'Three form feeds \f \f \f' 12 echo $'10 newlines \n\n\n\n\n\n\n\n\n\n' 13 echo $'\102\141\163\150' # Bash 14 # Octal equivalent of characters. 15 16 exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="VARREFNEW"></A></P><DIVCLASS="EXAMPLE"><HR><ANAME="EX78"></A><P><B>Example 34-2. Indirect variable references - the new way</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # Indirect variable referencing. 4 # This has a few of the attributes of references in C++. 5 6 7 a=letter_of_alphabet 8 letter_of_alphabet=z 9 10 echo "a = $a" # Direct reference. 11 12 echo "Now a = ${!a}" # Indirect reference. 13 # The ${!variable} notation is greatly superior to the old "eval var1=\$$var2" 14 15 echo 16 17 t=table_cell_3 18 table_cell_3=24 19 echo "t = ${!t}" # t = 24 20 table_cell_3=387 21 echo "Value of t changed to ${!t}" # 387 22 23 # This is useful for referencing members of an array or table, 24 #+ or for simulating a multi-dimensional array. 25 # An indexing option (analogous to pointer arithmetic) 26 #+ would have been nice. Sigh. 27 28 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="RESISTOR"></A><P><B>Example 34-3. Simple database application, using indirect variable referencing</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # resistor-inventory.sh 3 # Simple database application using indirect variable referencing. 4 5 # ============================================================== # 6 # Data 7 8 B1723_value=470 # Ohms 9 B1723_powerdissip=.25 # Watts 10 B1723_colorcode="yellow-violet-brown" # Color bands 11 B1723_loc=173 # Where they are 12 B1723_inventory=78 # How many 13 14 B1724_value=1000 15 B1724_powerdissip=.25 16 B1724_colorcode="brown-black-red" 17 B1724_loc=24N 18 B1724_inventory=243 19 20 B1725_value=10000 21 B1725_powerdissip=.25 22 B1725_colorcode="brown-black-orange" 23 B1725_loc=24N 24 B1725_inventory=89 25 26 # ============================================================== # 27 28 29 echo 30 31 PS3='Enter catalog number: ' 32 33 echo 34 35 select catalog_number in "B1723" "B1724" "B1725" 36 do 37 Inv=${catalog_number}_inventory 38 Val=${catalog_number}_value 39 Pdissip=${catalog_number}_powerdissip 40 Loc=${catalog_number}_loc 41 Ccode=${catalog_number}_colorcode 42 43 echo 44 echo "Catalog number $catalog_number:" 45 echo "There are ${!Inv} of [${!Val} ohm / ${!Pdissip} watt] resistors in stock." 46 echo "These are located in bin # ${!Loc}." 47 echo "Their color code is \"${!Ccode}\"." 48 49 break 50 done 51 52 echo; echo 53 54 # Exercises: 55 # --------- 56 # 1) Rewrite this script to read its data from an external file. 57 # 2) Rewrite this script to use arrays, 58 #+ rather than indirect variable referencing. 59 # Which method is more straightforward and intuitive? 60 61 62 # Notes: 63 # ----- 64 # Shell scripts are inappropriate for anything except the most simple 65 #+ database applications, and even then it involves workarounds and kludges. 66 # Much better is to use a language with native support for data structures, 67 #+ such as C++ or Java (or even Perl). 68 69 exit 0</PRE></TD></TR></TABLE><HR></DIV><DIVCLASS="EXAMPLE"><HR><ANAME="EX79"></A><P><B>Example 34-4. Using arrays and other miscellaneous trickery to deal four random hands from a deck of cards</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 3 # Cards: 4 # Deals four random hands from a deck of cards. 5 6 UNPICKED=0 7 PICKED=1 8 9 DUPE_CARD=99 10 11 LOWER_LIMIT=0 12 UPPER_LIMIT=51 13 CARDS_IN_SUIT=13 14 CARDS=52 15 16 declare -a Deck 17 declare -a Suits 18 declare -a Cards 19 # It would have been easier to implement and more intuitive 20 #+ with a single, 3-dimensional array. 21 # Perhaps a future version of Bash will support multidimensional arrays. 22 23 24 initialize_Deck () 25 { 26 i=$LOWER_LIMIT 27 until [ "$i" -gt $UPPER_LIMIT ] 28 do 29 Deck[i]=$UNPICKED # Set each card of "Deck" as unpicked. 30 let "i += 1" 31 done 32 echo 33 } 34 35 initialize_Suits () 36 { 37 Suits[0]=C #Clubs 38 Suits[1]=D #Diamonds 39 Suits[2]=H #Hearts 40 Suits[3]=S #Spades 41 } 42 43 initialize_Cards () 44 { 45 Cards=(2 3 4 5 6 7 8 9 10 J Q K A) 46 # Alternate method of initializing an array. 47 } 48 49 pick_a_card () 50 { 51 card_number=$RANDOM 52 let "card_number %= $CARDS" 53 if [ "${Deck[card_number]}" -eq $UNPICKED ] 54 then 55 Deck[card_number]=$PICKED 56 return $card_number 57 else 58 return $DUPE_CARD 59 fi 60 } 61 62 parse_card () 63 { 64 number=$1 65 let "suit_number = number / CARDS_IN_SUIT" 66 suit=${Suits[suit_number]} 67 echo -n "$suit-" 68 let "card_no = number % CARDS_IN_SUIT" 69 Card=${Cards[card_no]} 70 printf %-4s $Card 71 # Print cards in neat columns. 72 } 73 74 seed_random () # Seed random number generator. 75 { # What happens if you don't do this? 76 seed=`eval date +%s` 77 let "seed %= 32766" 78 RANDOM=$seed 79 # What are some other methods 80 #+ of seeding the random number generator? 81 } 82 83 deal_cards () 84 { 85 echo 86 87 cards_picked=0 88 while [ "$cards_picked" -le $UPPER_LIMIT ] 89 do 90 pick_a_card 91 t=$? 92 93 if [ "$t" -ne $DUPE_CARD ] 94 then 95 parse_card $t 96 97 u=$cards_picked+1 98 # Change back to 1-based indexing (temporarily). Why? 99 let "u %= $CARDS_IN_SUIT" 100 if [ "$u" -eq 0 ] # Nested if/then condition test. 101 then 102 echo 103 echo 104 fi 105 # Separate hands. 106 107 let "cards_picked += 1" 108 fi 109 done 110 111 echo 112 113 return 0 114 } 115 116 117 # Structured programming: 118 # Entire program logic modularized in functions. 119 120 #================ 121 seed_random 122 initialize_Deck 123 initialize_Suits 124 initialize_Cards 125 deal_cards 126 #================ 127 128 exit 0 129 130 131 132 # Exercise 1: 133 # Add comments to thoroughly document this script. 134 135 # Exercise 2: 136 # Add a routine (function) to print out each hand sorted in suits. 137 # You may add other bells and whistles if you like. 138 139 # Exercise 3: 140 # Simplify and streamline the logic of the script.</PRE></TD></TR></TABLE><HR></DIV></DIV></DIV><H3CLASS="FOOTNOTES">Notes</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN19239"HREF="bash2.html#AEN19239">[1]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>Chet Ramey has promised associative arrays (a nifty Perl feature) in a future Bash release. As of version 3.2, this has not yet happened.</P></TD></TR></TABLE><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="winscript.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="bashver3.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Shell Scripting Under Windows</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part5.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Bash, version 3</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -