文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>高级shell编程8(转载)

高级shell编程8(转载)

时间:2006-06-04  来源:lin_lin13

<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><title></title><meta name="GENERATOR" content="OpenOffice.org 2.0 (Linux)"><meta name="AUTHOR" content="lin lin"><meta name="CREATED" content="20060525;8284000"><meta name="CHANGEDBY" content="lin lin"><meta name="CHANGED" content="20060525;8323700"> <style> </style>

第8章 操作符和相关的主题

========================


8.1 操作符

----------


等号操作符


变量赋值

初始化或者修改变量的值

=

无论在算术运算还是字符串运算中,都是赋值语句.

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.



8.2 数字常量

------------

shell脚本默认都是将数字作为10进制数处理,除非这个数字某种特殊的标记法或前缀开头.

以0开头就是8进制.以0x开头就是16进制数.使用BASE#NUMBER这种形式可以表示其它进制

表示法


Example 8-4 数字常量的处理

################################Start Script#######################################

1 #!/bin/bash

2 # numbers.sh: 数字常量的几种不同的表示法

3

4 # 10进制: 默认

5 let "dec = 32"

6 echo "decimal number = $dec" # 32

7 # 一切都很正常

8

9

10 # 8进制: 以'0'(零)开头

11 let "oct = 032"

12 echo "octal number = $oct" # 26

13 # 表达式的结果用10进制表示.

14 #

15

16 # 16进制表示:数字以'0x'或者'0X'开头

17 let "hex = 0x32"

18 echo "hexadecimal number = $hex" # 50

19 # 表达式的结果用10进制表示.

20

21 # 其它进制: BASE#NUMBER

22 # BASE between 2 and 64.

22 # 2到64进制都可以.

23 # NUMBER必须在BASE的范围内,具体见下边.

24

25

26 let "bin = 2#111100111001101"

27 echo "binary number = $bin" # 31181

28

29 let "b32 = 32#77"

30 echo "base-32 number = $b32" # 231

31

32 let "b64 = 64#@_"

33 echo "base-64 number = $b64" # 4031

34 # 这种64进制的表示法中的每位数字都必须在64进制表示法的限制字符内.

35 # 10 个数字+ 26 个小写字母+ 26 个大写字母+ @ + _

36

37

38 echo

39

40 echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))

41 # 1295 170 44822 3375

42

43

44 # 重要的注意事项:

45 # ---------------

46 # 如果使用的每位数字超出了这个进制表示法规定字符的范围的话,

47 #+ 将给出一个错误消息.

48

49 let "bad_oct = 081"

50 # (部分的) 错误消息输出:

51 # bad_oct = 081: too great for base (error token is "081")

52 # Octal numbers use only digits in the range 0 - 7.

53

54 exit 0 # Thanks, Rich Bartell and Stephane Chazelas, for clarification.

################################End Script#########################################



相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载