📄 operations.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Operations and Related Topics</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Basics"HREF="part2.html"><LINKREL="PREVIOUS"TITLE="Testing Your Knowledge of Tests"HREF="testtest.html"><LINKREL="NEXT"TITLE="Numerical Constants"HREF="numerical-constants.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="testtest.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="numerical-constants.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="OPERATIONS"></A>Chapter 8. Operations and Related Topics</H1><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="OPS"></A>8.1. Operators</H1><DIVCLASS="VARIABLELIST"><P><B><ANAME="ASNOP1"></A>assignment</B></P><DL><DT><TTCLASS="REPLACEABLE"><I>variable assignment</I></TT></DT><DD><P>Initializing or changing the value of a variable</P></DD><DT>=</DT><DD><P>All-purpose assignment operator, which works for both arithmetic and string assignments.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 var=27 2 category=minerals # No spaces allowed after the "=".</PRE></TD></TR></TABLE> </P><DIVCLASS="CAUTION"><TABLECLASS="CAUTION"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/caution.png"HSPACE="5"ALT="Caution"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>Do not confuse the <SPANCLASS="QUOTE">"="</SPAN> assignment operator with the <AHREF="comparison-ops.html#EQUALSIGNREF">= test operator</A>.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 # = as a test operator 2 3 if [ "$string1" = "$string2" ] 4 then 5 command 6 fi 7 8 # if [ "X$string1" = "X$string2" ] is safer, 9 #+ to prevent an error message should one of the variables be empty. 10 # (The prepended "X" characters cancel out.)</PRE></TD></TR></TABLE> </P></TD></TR></TABLE></DIV></DD></DL></DIV><DIVCLASS="VARIABLELIST"><P><B><ANAME="AROPS1"></A>arithmetic operators</B></P><DL><DT><SPANCLASS="TOKEN">+</SPAN></DT><DD><P>plus</P></DD><DT><SPANCLASS="TOKEN">-</SPAN></DT><DD><P>minus</P></DD><DT><SPANCLASS="TOKEN">*</SPAN></DT><DD><P>multiplication</P></DD><DT><SPANCLASS="TOKEN">/</SPAN></DT><DD><P>division</P></DD><DT><ANAME="EXPONENTIATIONREF"></A><SPANCLASS="TOKEN">**</SPAN></DT><DD><P>exponentiation</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 # Bash, version 2.02, introduced the "**" exponentiation operator. 2 3 let "z=5**3" 4 echo "z = $z" # z = 125</PRE></TD></TR></TABLE> </P></DD><DT><ANAME="MODULOREF"></A><SPANCLASS="TOKEN">%</SPAN></DT><DD><P>modulo, or mod (returns the <ICLASS="FIRSTTERM">remainder</I> of an integer division operation)</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="SCREEN"> <TTCLASS="PROMPT">bash$ </TT><TTCLASS="USERINPUT"><B>expr 5 % 3</B></TT> <TTCLASS="COMPUTEROUTPUT">2</TT> </PRE></TD></TR></TABLE> <SPANCLASS="emphasis"><ICLASS="EMPHASIS">5/3 = 1 with remainder 2</I></SPAN> </P><P>This operator finds use in, among other things, generating numbers within a specific range (see <AHREF="randomvar.html#EX21">Example 9-26</A> and <AHREF="randomvar.html#RANDOMTEST">Example 9-30</A>) and formatting program output (see <AHREF="arrays.html#QFUNCTION">Example 26-16</A> and <AHREF="contributed-scripts.html#COLLATZ">Example A-6</A>). It can even be used to generate prime numbers, (see <AHREF="contributed-scripts.html#PRIMES">Example A-16</A>). Modulo turns up surprisingly often in various numerical recipes.</P><DIVCLASS="EXAMPLE"><HR><ANAME="GCD"></A><P><B>Example 8-1. Greatest common divisor</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # gcd.sh: greatest common divisor 3 # Uses Euclid's algorithm 4 5 # The "greatest common divisor" (gcd) of two integers 6 #+ is the largest integer that will divide both, leaving no remainder. 7 8 # Euclid's algorithm uses successive division. 9 # In each pass, 10 #+ dividend <--- divisor 11 #+ divisor <--- remainder 12 #+ until remainder = 0. 13 #+ The gcd = dividend, on the final pass. 14 # 15 # For an excellent discussion of Euclid's algorithm, see 16 #+ Jim Loy's site, http://www.jimloy.com/number/euclids.htm. 17 18 19 # ------------------------------------------------------ 20 # Argument check 21 ARGS=2 22 E_BADARGS=65 23 24 if [ $# -ne "$ARGS" ] 25 then 26 echo "Usage: `basename $0` first-number second-number" 27 exit $E_BADARGS 28 fi 29 # ------------------------------------------------------ 30 31 32 gcd () 33 { 34 35 dividend=$1 # Arbitrary assignment. 36 divisor=$2 #! It doesn't matter which of the two is larger. 37 # Why not? 38 39 remainder=1 # If uninitialized variable used in loop, 40 #+ it results in an error message 41 #+ on the first pass through loop. 42 43 until [ "$remainder" -eq 0 ] 44 do 45 let "remainder = $dividend % $divisor" 46 dividend=$divisor # Now repeat with 2 smallest numbers. 47 divisor=$remainder 48 done # Euclid's algorithm 49 50 } # Last $dividend is the gcd. 51 52 53 gcd $1 $2 54 55 echo; echo "GCD of $1 and $2 = $dividend"; echo 56 57 58 # Exercise : 59 # -------- 60 # Check command-line arguments to make sure they are integers, 61 #+ and exit the script with an appropriate error message if not. 62 63 exit 0</PRE></TD></TR></TABLE><HR></DIV></DD><DT><ANAME="ARITHOPSCOMB"></A><SPANCLASS="TOKEN">+=</SPAN></DT><DD><P><ICLASS="FIRSTTERM">plus-equal</I> (increment variable by a constant)</P><P><TTCLASS="USERINPUT"><B>let "var += 5"</B></TT> results in <TTCLASS="PARAMETER"><I>var</I></TT> being incremented by <TTCLASS="LITERAL">5</TT>.</P></DD><DT><SPANCLASS="TOKEN">-=</SPAN></DT><DD><P><ICLASS="FIRSTTERM">minus-equal</I> (decrement variable by a constant)</P></DD><DT><SPANCLASS="TOKEN">*=</SPAN></DT><DD><P><ICLASS="FIRSTTERM">times-equal</I> (multiply variable by a constant)</P><P><TTCLASS="USERINPUT"><B>let "var *= 4"</B></TT> results in <TTCLASS="PARAMETER"><I>var</I></TT> being multiplied by <TTCLASS="LITERAL">4</TT>.</P></DD><DT><SPANCLASS="TOKEN">/=</SPAN></DT><DD><P><ICLASS="FIRSTTERM">slash-equal</I> (divide variable by a constant)</P></DD><DT><SPANCLASS="TOKEN">%=</SPAN></DT><DD><P><ICLASS="FIRSTTERM">mod-equal</I> (remainder of dividing variable by a constant)</P><P><SPANCLASS="emphasis"><ICLASS="EMPHASIS">Arithmetic operators often occur in an <AHREF="moreadv.html#EXPRREF">expr</A> or <AHREF="internal.html#LETREF">let</A> expression.</I></SPAN></P><DIVCLASS="EXAMPLE"><HR><ANAME="ARITHOPS"></A><P><B>Example 8-2. Using Arithmetic Operations</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # Counting to 11 in 10 different ways. 3 4 n=1; echo -n "$n " 5 6 let "n = $n + 1" # let "n = n + 1" also works. 7 echo -n "$n " 8 9 10 : $((n = $n + 1)) 11 # ":" necessary because otherwise Bash attempts 12 #+ to interpret "$((n = $n + 1))" as a command. 13 echo -n "$n " 14 15 (( n = n + 1 )) 16 # A simpler alternative to the method above. 17 # Thanks, David Lombard, for pointing this out. 18 echo -n "$n " 19 20 n=$(($n + 1)) 21 echo -n "$n " 22 23 : $[ n = $n + 1 ] 24 # ":" necessary because otherwise Bash attempts 25 #+ to interpret "$[ n = $n + 1 ]" as a command. 26 # Works even if "n" was initialized as a string. 27 echo -n "$n " 28 29 n=$[ $n + 1 ] 30 # Works even if "n" was initialized as a string. 31 #* Avoid this type of construct, since it is obsolete and nonportable. 32 # Thanks, Stephane Chazelas. 33 echo -n "$n " 34 35 # Now for C-style increment operators. 36 # Thanks, Frank Wang, for pointing this out. 37 38 let "n++" # let "++n" also works. 39 echo -n "$n " 40 41 (( n++ )) # (( ++n ) also works. 42 echo -n "$n " 43 44 : $(( n++ )) # : $(( ++n )) also works. 45 echo -n "$n " 46 47 : $[ n++ ] # : $[ ++n ]] also works 48 echo -n "$n " 49 50 echo 51 52 exit 0</PRE></TD></TR></TABLE><HR></DIV></DD></DL></DIV><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>Integer variables in Bash are actually signed <ICLASS="FIRSTTERM">long</I> (32-bit) integers, in the range of -2147483648 to 2147483647. An operation that takes a variable outside these limits will give an erroneous result.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 a=2147483646 2 echo "a = $a" # a = 2147483646 3 let "a+=1" # Increment "a". 4 echo "a = $a" # a = 2147483647 5 let "a+=1" # increment "a" again, past the limit. 6 echo "a = $a" # a = -2147483648 7 # ERROR (out of range)</PRE></TD></TR></TABLE> </P><P
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -