----------
等号操作符
变量赋值 初始化或者修改变量的值 = 无论在算术运算还是字符串运算中,都是赋值语句. 1 var=27 2 category=minerals # No spaces allowed after the "=".
注意:不要和"="test操作符混淆. 1 # = as a test operator 2 3 if [ "$string1" = "$string2" ] 4 # if [ "X$string1" = "X$string2" ] is safer, 5 # to prevent an error message should one of the variables be empty. 6 # (The prepended "X" characters cancel out.) 7 then 8 command 9 fi
算术操作符
+ 加法 - 减法 * 乘法 / 除法 ** 幂运算 1 # Bash, version 2.02, introduced the "**" exponentiation operator. 2 3 let "z=5**3" 4 echo "z = $z" # z = 125 % 取模 bash$ expr 5 % 3 2
5/3=1余2 模运算经常用在其它的事情中,比如产生特定的范围的数字(Example 9-24, Example 9-27)和格式化程序的输出(Example 26-15,Example A-6).它甚至可以用来 产生质数,(Example A-16).事实上取模运算在算术运算中使用的频率惊人的高.
Example 8-1 最大公约数 ################################Start Script####################################### 1 #!/bin/bash 2 # gcd.sh: 最大公约数 3 # 使用Euclid's 算法 4 5 # 最大公约数,就是2个数能够同时整除的最大的数. 6 # 7 8 # Euclid's算法采用连续除法. 9 # 在每个循环中 10 #+ 被除数 <--- 除数 11 #+ 除数 <--- 余数 12 #+ 直到余数= 0. 13 #+ 在最后的循环中The gcd = 被除数 14 # 15 # 关于这个算法更精彩的讨论 16 # 见Jim Loy's site, 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 #+ 即使$2大,也没关系. 37 # Why not? 38 39 remainder=1 # 如果再循环中使用为初始化的变量. 40 #+ 那将在第一次循环中产生一个错误消息. 41 42 43 until [ "$remainder" -eq 0 ] 44 do 45 let "remainder = $dividend % $divisor" 46 dividend=$divisor # 现在使用2个最小的数重复. 47 divisor=$remainder 48 done # Euclid's algorithm 49 50 } # Last $dividend is the gcd. 50 } # 最后的$dividend就是gcd. 51 52 53 gcd $1 $2 54 55 echo; echo "GCD of $1 and $2 = $dividend"; echo 56 57 58 # 练习: 59 # -------- 60 # 检查命令行参数来确定它们都是整数, 61 #+ and exit the script with an appropriate error message if not. 61 #+ 否则就选择合适的错误消息退出. 62 63 exit 0 ################################End Script#########################################
+= 加等于(通过常量增加变量) let "var += 5" #var将在本身值的基础上增加5 -= 减等于 *= 乘等于 let "var *= 4" /= 除等于 %= 取模赋值,算术操作经常使用expr或者let表达式.
Example 8-2 使用算术操作符 ################################Start Script####################################### 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" 这么写也行 7 echo -n "$n " 8 9 10 : $((n = $n + 1)) 11 # ":" 是必须的,这是因为,如果没有":"的话,Bash将 12 #+ 尝试把"$((n = $n + 1))"解释成一个命令 13 echo -n "$n " 14 15 (( n = n + 1 )) 16 # 对于上边的方法的一个更简单的选则. 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 # ":" 是必须的,这是因为,如果没有":"的话,Bash将 25 #+ 尝试把"$[ n = $n + 1 ]" 解释成一个命令 26 # 即使"n"被初始化成为一个字符串,这句也能工作. 27 echo -n "$n " 28 29 n=$[ $n + 1 ] 30 # 即使"n"被初始化成为一个字符串,这句也能工作. 31 #* Avoid this type of construct, since it is obsolete and nonportable. 31 #* 尽量避免这种类型的结果,因为这已经被废弃了,并且不具可移植性. 32 # Thanks, Stephane Chazelas. 33 echo -n "$n " 34 35 # 现在来个C风格的增量操作. 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 ################################End Script#########################################
注意:在Bash中的整型变量事实上是32位的,范围是 -2147483648 到2147483647.如果超过这个 范围进行算术操作,将不会得到你期望的结果(就是溢出么). 1 a=2147483646 2 echo "a = $a" # a = 2147483646 3 let "a+=1" # 加1 "a". 4 echo "a = $a" # a = 2147483647 5 let "a+=1" # 再加1 "a" ,将超过上限了. 6 echo "a = $a" # a = -2147483648 7 # 错误 (溢出了) 在Bash 2.05b版本中,Bash支持64位整型了.
注意:Bash并不能理解浮点运算.它把包含的小数点看作字符串. 1 a=1.5 2 3 let "b = $a + 1.3" # 错误. 4 # t2.sh: let: b = 1.5 + 1.3: 表达式的语义错误(错误标志为".5 + 1.3") 5 6 echo "b = $b" # b=1 如果真想做浮点运算的话,使用bc(见12.8节),bc可以进行浮点运算或调用数学库函数.
位操作符. (晕,有点强大过分了吧,位级操作都支持.) 位操作符在shell脚本中极少使用.它们最主要的用途看起来就是操作和test从sockets中 读出的变量."Bit flipping"与编译语言的联系很紧密,比如c/c++,在这种语言中它可以 运行得足够快.(原文有处on the fly,我查了一下,好像是没事干的意思,没理解)
<< 左移1位(每次左移都将乘2)
<<= 左移几位,=号后边将给出左移几位 let "var <<= 2"就是左移2位(就是乘4)
>> 右移1位(每次右移都将除2)
>>= 右移几位
& 按位与
&= 按位与赋值
| 按位或
|= 按位或赋值
~ 按位非
! 按位否?(没理解和上边的~有什么区别?),感觉是应该放到下边的逻辑操作中
^ 按位异或XOR
^= 异或赋值
逻辑操作:
&& 逻辑与 1 if [ $condition1 ] && [ $condition2 ] 2 # 与: if [ $condition1 -a $condition2 ] 相同 3 # 如果condition1和condition2都为true,那结果就为true. 4 5 if [[ $condition1 && $condition2 ]] # 也可以. 6 # 注意&&不允许出现在[ ... ]中. 注意:&&也可以用在and list中(见25章),但是使用的时候需要依赖上下文.
|| 逻辑或 1 if [ $condition1 ] || [ $condition2 ] 2 # 与: if [ $condition1 -o $condition2 ] 相同 3 # 如果condition1或condition2为true,那结果就为true. 4 5 if [[ $condition1 || $condition2 ]] # 也可以 6 # 注意||不允许出现在[ ... ]中. 注意:Bash将test每个连接到逻辑操作的状态的退出状态(见第6章).
Example 8-3 使用&&和||进行混合状态的test ################################Start Script####################################### 1 #!/bin/bash 2 3 a=24 4 b=47 5 6 if [ "$a" -eq 24 ] && [ "$b" -eq 47 ] 7 then 8 echo "Test #1 succeeds." 9 else 10 echo "Test #1 fails." 11 fi 12 13 # 错误: if [ "$a" -eq 24 && "$b" -eq 47 ] 14 #+ 尝试执行' [ "$a" -eq 24 ' 15 #+ 因为没找到']'所以失败了. 16 # 17 # 注意: 如果 [[ $a -eq 24 && $b -eq 24 ]] 能够工作. 18 # 那这个[[]]的test结构就比[]结构更灵活了. 19 # 20 # (在17行的"&&"与第6行的"&&"意义不同) 21 # Thanks, Stephane Chazelas, for pointing this out. 22 23 24 if [ "$a" -eq 98 ] || [ "$b" -eq 47 ] 25 then 26 echo "Test #2 succeeds." 27 else 28 echo "Test #2 fails." 29 fi 30 31 32 # -a和-o选项提供了 33 #+ 一种可选的混合test方法. 34 # Thanks to Patrick Callahan for pointing this out. 35 36 37 if [ "$a" -eq 24 -a "$b" -eq 47 ] 38 then 39 echo "Test #3 succeeds." 40 else 41 echo "Test #3 fails." 42 fi 43 44 45 if [ "$a" -eq 98 -o "$b" -eq 47 ] 46 then 47 echo "Test #4 succeeds." 48 else 49 echo "Test #4 fails." 50 fi 51 52 53 a=rhino 54 b=crocodile 55 if [ "$a" = rhino ] && [ "$b" = crocodile ] 56 then 57 echo "Test #5 succeeds." 58 else 59 echo "Test #5 fails." 60 fi 61 62 exit 0 ################################End Script######################################### &&和||操作也能在算术运算的上下文中找到. bash$ echo $(( 1 && 2 )) $((3 && 0)) $((4 || 0)) $((0 || 0)) 1 0 1 0
混杂操作: , 逗号操作符 逗号操作符可以连接2个或多个算术运算.所有的操作都会被执行,但是只有最后一个 操作作为结果. 1 let "t1 = ((5 + 3, 7 - 1, 15 - 4))" 2 echo "t1 = $t1" # t1 = 11 3 4 let "t2 = ((a = 9, 15 / 3))" # Set "a" and calculate "t2". 5 echo "t2 = $t2 a = $a" # t2 = 5 a = 9 ","主要用在for循环中,具体见Example 10-12. |