ops.html
来自「BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版」· HTML 代码 · 共 1,274 行 · 第 1/2 页
HTML
1,274 行
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><HTML><HEAD><TITLE>操作符</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINKREL="HOME"TITLE="高级Bash脚本编程指南"HREF="index.html"><LINKREL="UP"TITLE="操作符与相关主题"HREF="operations.html"><LINKREL="PREVIOUS"TITLE="操作符与相关主题"HREF="operations.html"><LINKREL="NEXT"TITLE="数字常量"HREF="numerical-constants.html"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">高级Bash脚本编程指南: 一本深入学习shell脚本艺术的书籍</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="operations.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">8. 操作符与相关主题</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="numerical-constants.html"ACCESSKEY="N">下一页</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="OPS">8.1. 操作符</A></H1><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="ASNOP1"></A>赋值</B></P><DL><DT><TTCLASS="REPLACEABLE"><I>变量赋值</I></TT></DT><DD><P>初始化或者修改变量的值</P></DD><DT>=</DT><DD><P>通用赋值操作符, 可用于算术和字符串赋值. </P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 var=27 2 category=minerals # 在"="之后是不允许出现空白字符的.</PRE></FONT></TD></TR></TABLE> </P><DIVCLASS="CAUTION"><P></P><TABLECLASS="CAUTION"WIDTH="90%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/caution.gif"HSPACE="5"ALT="Caution"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>不要混淆<SPANCLASS="QUOTE">"="</SPAN>赋值操作符与<AHREF="comparison-ops.html#EQUALSIGNREF">=</A>测试操作符.</P><P> <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 # = 在这里是测试操作符 2 3 if [ "$string1" = "$string2" ] 4 # if [ "X$string1" = "X$string2" ] 是一种更安全的做法, 5 # 这样可以防止两个变量中的一个为空所产生的错误. 6 # (字符"X"作为前缀在等式两边是可以相互抵消的.) 7 then 8 command 9 fi</PRE></FONT></TD></TR></TABLE> </P></TD></TR></TABLE></DIV></DD></DL></DIV><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="AROPS1"></A>算术操作符</B></P><DL><DT><SPANCLASS="TOKEN">+</SPAN></DT><DD><P>加法计算</P></DD><DT><SPANCLASS="TOKEN">-</SPAN></DT><DD><P>减法计算</P></DD><DT><SPANCLASS="TOKEN">*</SPAN></DT><DD><P>乘法计算</P></DD><DT><SPANCLASS="TOKEN">/</SPAN></DT><DD><P>除法计算</P></DD><DT><ANAME="EXPONENTIATIONREF"></A><SPANCLASS="TOKEN">**</SPAN></DT><DD><P>幂运算 <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 # 在Bash, 版本2.02, 中开始引入了"**" 幂运算符. 2 3 let "z=5**3" 4 echo "z = $z" # z = 125</PRE></FONT></TD></TR></TABLE> </P></DD><DT><ANAME="MODULOREF"></A><SPANCLASS="TOKEN">%</SPAN></DT><DD><P>模运算, 或者是求余运算(返回一次除法运算的<ICLASS="FIRSTTERM">余数</I>)</P><P> <TABLEBORDER="1"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="SCREEN"><SAMPCLASS="PROMPT">bash$ </SAMP><KBDCLASS="USERINPUT">expr 5 % 3</KBD><SAMPCLASS="COMPUTEROUTPUT">2</SAMP> </PRE></FONT></TD></TR></TABLE> <EM>5/3 = 1 余数为 2</EM> </P><P>模运算经常在其他的一些情况中出现, 比如说产生特定范围的数字(参见<AHREF="randomvar.html#EX21">例子 9-25</A>和<AHREF="randomvar.html#RANDOMTEST">例子 9-28</A>), 或者格式化程序的输出(参见<AHREF="arrays.html#QFUNCTION">例子 26-15</A>和<AHREF="contributed-scripts.html#COLLATZ">例子 A-6</A>). 它甚至可以用来产生质数, (参见<AHREF="contributed-scripts.html#PRIMES">例子 A-16</A>). 事实上模运算在算术运算中的使用频率高得惊人. </P><DIVCLASS="EXAMPLE"><HR><ANAME="GCD"></A><P><B>例子 8-1. 最大公约数</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # gcd.sh: 最大公约数 3 # 使用Euclid的算法 4 5 # 两个整数的"最大公约数" (gcd), 6 #+ 就是两个整数所能够同时整除的最大的数. 7 8 # Euclid算法采用连续除法. 9 # 在每一次循环中, 10 #+ 被除数 <--- 除数 11 #+ 除数 <--- 余数 12 #+ 直到 余数 = 0. 13 #+ 在最后一次循环中, gcd = 被除数. 14 # 15 # 关于Euclid算法的更精彩的讨论, 可以到 16 #+ Jim Loy的站点, http://www.jimloy.com/number/euclids.htm. 17 18 19 # ------------------------------------------------------ 20 # 参数检查 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 # 随意赋值. 36 divisor=$2 #+ 在这里, 哪个值给的大都没关系. 37 # 为什么没关系? 38 39 remainder=1 # 如果在循环中使用了未初始化的变量, 40 #+ 那么在第一次循环中, 41 #+ 它将会产生一个错误消息. 42 43 until [ "$remainder" -eq 0 ] 44 do 45 let "remainder = $dividend % $divisor" 46 dividend=$divisor # 现在使用两个最小的数来重复. 47 divisor=$remainder 48 done # Euclid的算法 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 # 检查传递进来的命令行参数来确保它们都是整数. 61 #+ 如果不是整数, 那就给出一个适当的错误消息并退出脚本. 62 63 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DD><DT><SPANCLASS="TOKEN">+=</SPAN></DT><DD><P><SPANCLASS="QUOTE">"加-等于"</SPAN> (把变量的值增加一个常量然后再把结果赋给变量)</P><P><KBDCLASS="USERINPUT">let "var += 5"</KBD> <CODECLASS="VARNAME">var</CODE>变量的值会在原来的基础上加<TTCLASS="LITERAL">5</TT>.</P></DD><DT><SPANCLASS="TOKEN">-=</SPAN></DT><DD><P><SPANCLASS="QUOTE">"减-等于"</SPAN> (把变量的值减去一个常量然后再把结果赋给变量)</P></DD><DT><SPANCLASS="TOKEN">*=</SPAN></DT><DD><P><SPANCLASS="QUOTE">"乘-等于"</SPAN> (先把变量的值乘以一个常量的值, 然后再把结果赋给变量)</P><P><KBDCLASS="USERINPUT">let "var *= 4"</KBD> <CODECLASS="VARNAME">var</CODE>变量的结果将会在原来的基础上乘以<TTCLASS="LITERAL">4</TT>.</P></DD><DT><SPANCLASS="TOKEN">/=</SPAN></DT><DD><P><SPANCLASS="QUOTE">"除-等于"</SPAN> (先把变量的值除以一个常量的值, 然后再把结果赋给变量)</P></DD><DT><SPANCLASS="TOKEN">%=</SPAN></DT><DD><P><SPANCLASS="QUOTE">"取模-等于"</SPAN> (先对变量进行模运算, 即除以一个常量取模, 然后把结果赋给变量)</P><P><EM>算术操作符经常会出现在 <AHREF="moreadv.html#EXPRREF">expr</A>或<AHREF="internal.html#LETREF">let</A>表达式中.</EM></P><DIVCLASS="EXAMPLE"><HR><ANAME="ARITHOPS"></A><P><B>例子 8-2. 使用算术操作符</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # 使用10种不同的方法计数到11. 3 4 n=1; echo -n "$n " 5 6 let "n = $n + 1" # let "n = n + 1" 也可以. 7 echo -n "$n " 8 9 10 : $((n = $n + 1)) 11 # ":" 是必需的, 因为如果没有":"的话, 12 #+ Bash将会尝试把"$((n = $n + 1))"解释为一个命令. 13 echo -n "$n " 14 15 (( n = n + 1 )) 16 # 上边这句是一种更简单方法. 17 # 感谢, David Lombard, 指出这点. 18 echo -n "$n " 19 20 n=$(($n + 1)) 21 echo -n "$n " 22 23 : $[ n = $n + 1 ] 24 # ":" 是必需的, 因为如果没有":"的话, 25 #+ Bash将会尝试把"$[ n = $n + 1 ]"解释为一个命令. 26 # 即使"n"被初始化为字符串, 这句也能够正常运行. 27 echo -n "$n " 28 29 n=$[ $n + 1 ] 30 # 即使"n"被初始化为字符串, 这句也能够正常运行. 31 #* 应该尽量避免使用这种类型的结构, 因为它已经被废弃了, 而且不具可移植性. 32 # 感谢, Stephane Chazelas. 33 echo -n "$n " 34 35 # 现在来一个C风格的增量操作. 36 # 感谢, Frank Wang, 指出这点. 37 38 let "n++" # let "++n" 也可以. 39 echo -n "$n " 40 41 (( n++ )) # (( ++n ) 也可以. 42 echo -n "$n " 43 44 : $(( n++ )) # : $(( ++n )) 也可以. 45 echo -n "$n " 46 47 : $[ n++ ] # : $[ ++n ]] 也可以. 48 echo -n "$n " 49 50 echo 51 52 exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV></DD></DL></DIV><DIVCLASS="NOTE"><P></P><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="./images/note.gif"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>在Bash中的整型变量事实上是一个有符号的<EM>long</EM>(32-bit)整型值, 所表示的范围是-2147483648到2147483647. 如果超过这个范围进行算术操作的话, 那么将不会得到你期望的结果.(译者注: 溢出) <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING"> 1 a=2147483646 2 echo "a = $a" # a = 2147483646 3 let "a+=1" # 变量"a"加1. 4 echo "a = $a" # a = 2147483647 5 let "a+=1" # 变量"a"再加1, 就会超出范围限制了. 6 echo "a = $a" # a = -2147483648 7 # 错误(超出范围了)</PRE></FONT
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?