专注各种脚本编程
Baidu
加入收藏夹
本站内容有下面分类知识,欢迎您的到来^_^
shell相关:指令篇 基础篇 脚本欣赏 编程实例 shell问问 shell视频教程 技巧篇 水平测试 E文资料 vi编辑器 高级Bash脚本编程指南
其他:mysql perl c语言 oracle
当前位置:| 主页>高级Bash脚本编程指南>

8.1 操作符

百度收藏 QQ搜藏

----------

等号操作符

变量赋值
 初始化或者修改变量的值
=
 无论在算术运算还是字符串运算中,都是赋值语句.
 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.

上一篇:7.5 检查你的test知识 下一篇:8.2 数字常量

power by soyo123 2007-2008