shell浅谈之别名、列表及数组

来源:互联网 发布:手机淘宝客服图片 编辑:程序博客网 时间:2024/05/21 22:24

一、简介

       Linux Shell编程中也会使用到函数,函数可以把大的命令集合分解成若干较小的任务,也避免重复编写相同的代码。在Shell中,所有的函数定义都是平行的,即不允许在函数体内再定义其他的函数,但允许函数之间相互调用。函数又涉及到很多基本使用:函数参数调用、函数返回值、局部变量及全局变量、函数间的相互调用和函数递归调用。

二、详解

1、函数的定义

(1)函数是一串命令的集合,如果脚本中有重复代码时可以考虑使用函数,在shell中函数的返回值只能为退出状态0或1。应注意函数名在脚本中的唯一。可以在函数名前加上fuction关键字也可省略。函数体中的命令集合必须含有至少一条命令(函数不允许空命令,与C不同)。

(2)脚本遇到"hello(){"结构时,知道定义了一个名为hello的函数,而且它会记住hello代表的函数,并执行函数体中的命令,直到出现"}"字符结束,当执行到单独的行hello时,shell就知道应该去执行刚才定义的函数,执行完毕返回继续执行其他的命令或函数。在shell中不需要申明就可直接定义函数,但在调用函数前需对它进行定义。如下是shell脚本中循环调用函数的例子:

[cpp] view plaincopy
  1. #function2.sh  
  2. #!/bin/bash  
  3.   
  4. output()  
  5. {  
  6.      for(( num1 = 1; num1 <= 5; num1++ ))  
  7.      do  
  8.          echo -n "$num1 "  
  9.      done   
  10. }  
  11.   
  12. let "num2=1"  
  13. while [ "$num2" -le 5 ]  
  14. do  
  15.     output  
  16.     echo ""  
  17.     let "num2=num2 + 1"  
  18. done  

(3)判断当前目录下存在多少个文件和子目录

[cpp] view plaincopy
  1. #显示当前目录下文件和目录数  
  2. #function3.sh  
  3. #!/bin/bash  
  4.   
  5. directory()  
  6. {  
  7.     let "filenum = 0"  
  8.     let "dirnum = 0"  
  9.       
  10.     ls  
  11.     echo ""                 #echo换行  
  12.       
  13.     for file in $( ls )     #for循环判断当前子目录和文件  
  14.     do  
  15.         if [ -d $file ]     #判断为子目录  
  16.         then  
  17.             let "dirnum = dirnum + 1"  
  18.         else                #判断为文件  
  19.            let "filenum = filenum + 1"  
  20.         fi  
  21.     done  
  22.   
  23.     echo "The number of directory is $dirnum"  
  24.     echo "The number of file is $filenum"  
  25. }  
  26.   
  27. directory                  #在脚本中调用函数  

2、向函数传递参数

      shell中,向函数传递的参数仍然是以位置参数的方式来传递的,而不能传递数组等其他形式变量(与c不同)。利用函数参数的传递实现两数的四则运算。

[cpp] view plaincopy
  1. #用于实现两数加、减、乘和除四则运算  
  2. #!/bin/bash  
  3.   
  4. count()  
  5. {  
  6.     if [ $# -ne 3 ]             #3个参数,一个运算符两个数值  
  7.     then   
  8.         echo "The  number of arguments is not 3! "  
  9.     fi  
  10.       
  11.     let "s = 0"  
  12.     case $2 in  
  13.     +)                          #加法  
  14.         let "s = $1 + $3"  
  15.         echo "$1 + $3 = $s";;  
  16.     -)                          #减法  
  17.         let "s = $1 - $3"  
  18.         echo "$1 - $3 = $s";;  
  19.     \*)                         #乘法  
  20.        let "s = $1 * $3"  
  21.        echo "$1 * $3 = $s";;  
  22.      \/)                        #除法-取余,浮点数运算使用bc  
  23.         let "s = $1 / $3"  
  24.         echo "$1 / $3 = $s";;  
  25.     *)                          #其他  
  26.         echo "What you input is wrong!";;  
  27.     esac  
  28. }  
  29.   
  30. echo "Please type your word: ( e.g. 1 + 1 )"  
  31. read a b c   
  32. count $a $b $c  

3、函数返回值

      有时需要函数执行完成后返回特定的值来完成脚本的后续操作。函数通过return返回退出状态,0表示true无错误,非0表示false有错误(与C不同)。

[cpp] view plaincopy
  1. #根据用户输入显示星期  
  2. #!/bin/bash  
  3.   
  4. show_week()  
  5. {  
  6.      echo -n "What you input is: "  
  7.      echo "$1"  
  8.   
  9.     case $1 in   
  10.     0)  
  11.         echo "Today is Sunday. "  
  12.         return 0;;  
  13.     1)  
  14.         echo "Today is Monday. "  
  15.         return 0;;  
  16.     2)  
  17.         echo "Today is Tuesday. "  
  18.         return 0;;  
  19.     3)  
  20.         echo "Today is Wednesday. "  
  21.         return 0;;  
  22.     4)  
  23.         echo "Today is Thursday. "  
  24.         return 0;;  
  25.     5)  
  26.         echo "Today is Friday. "  
  27.         return 0;;  
  28.     6)  
  29.         echo "Today is Saturday. "  
  30.         return 0;;  
  31.     *)  
  32.         return 1;;  
  33.     esac  
  34. }  
  35.   
  36. #if show_week "$1"          #返回0表示函数输入的命令行参数是正确的  
  37. #也可以通过$?来获取函数执行的返回值  
  38. show_week "$1"  
  39. if [ $? -eq 0 ]  
  40. then  
  41.     echo "What you input is right! "  
  42. else   
  43.     echo "What you input is wrong! "  
  44. fi  
  45. exit 0  

4、函数调用

shell脚本中可以同时放置多个函数,函数之间允许相互调用,而且允许一个函数调用多个函数。

[cpp] view plaincopy
  1. #用于显示一个不多于5位的正整数的位数,并按顺序显示各个数位的值  
  2. #!/bin/bash  
  3.   
  4. count_of_int()  
  5. {  
  6.     if [ $1 -gt 9999 ]  
  7.     then  
  8.         let "place=5"         #5位数  
  9.     elif [ $1 -gt 999 ]  
  10.     then  
  11.         let "place=4"  
  12.     elif [ $1 -gt 99 ]  
  13.     then  
  14.         let "place=3"  
  15.     elif [ $1 -gt 9 ]  
  16.     then  
  17.        let "place=2"  
  18.     else  
  19.         let "place=1"         #1位数  
  20.     fi  
  21.       
  22.     echo "The place of the $1 is $place."      #整数的位数  
  23. }   
  24.   
  25. num_of_int()  
  26. {  
  27.     let "ten_thousand = $1/10000"           #整数的数位分解值      
  28.     let "thousand =$1/1000%10"  
  29.     let "hundred = $1/100%10"  
  30.     let "ten = $1%100/10"  
  31.     let "indiv = $1%10"  
  32.   
  33.     if [ $ten_thousand -ne 0 ]  
  34.     then  
  35.        echo "$ten_thousand  $thousand  $hundred  $ten  $indiv"  
  36.     elif [ $thousand -ne 0 ]  
  37.     then  
  38.         echo "$thousand  $hundred  $ten  $indiv"  
  39.     elif [ $hundred -ne 0 ]  
  40.     then  
  41.         echo "$hundred  $ten  $indiv"  
  42.     elif [ $ten -ne 0 ]  
  43.     then  
  44.        echo "$ten  $indiv"  
  45.     else  
  46.        echo "$indiv"  
  47.     fi  
  48. }  
  49.   
  50. show()  
  51. {  
  52.     echo "Please input the number(1-99999): "  
  53.     read num  
  54.      
  55.     count_of_int $num  
  56.     num_of_int $num  
  57. }  
  58.   
  59. show  

执行脚本,输入整数2014,该数是四位数,千位是2,百位是0,十位是1,个位是4。

5、函数中局部和全局变量

      shell中,可以通过local关键字来申明局部变量,局部变量将局限在函数范围内。函数可调用函数外的全局变量,若一个局部变量和一个全局变量的名字相同,则在函数中局部变量会覆盖掉全局变量。

[cpp] view plaincopy
  1. #!/bin/bash  
  2.   
  3. text="global variable"  
  4.   
  5. use_local_var_fun()  
  6. {  
  7.     local text="local variable"          #local声明为局部变量,否则会修改全局text的值  
  8.     echo "in function------"$text        #暂时覆盖掉全局变量的值  
  9. }  
  10.   
  11. use_local_var_fun  
  12.   
  13. echo "Out of function------"$text        #text的值为开始定义的值  
  14. exit 0  

6、函数递归

(1)shell中执行递归函数可以直接或间接地反复调用其自身,每调用一层就进入新的一层,主调函数又是被调函数。

(2)使用局部变量进行递归实现阶乘运算,也可采用递推法实现。

[cpp] view plaincopy
  1. #阶乘运算,当n=0时 0!=1,当n>=1时n!=n*(n-1)!  
  2. #!/bin/bash  
  3.   
  4. fact ()  
  5. {  
  6.     local num=$1         #函数需将先前的局部值进行逐个还原,故设置成局部的变量  
  7.     echo $num  
  8.       
  9.     if [ "$num" -eq 0 ]  
  10.     then  
  11.         factorial=1  
  12.     else  
  13.         let "decnum=num-1"  
  14.   
  15.         fact $decnum  
  16.   
  17.         let "factorial=$num * $?"  
  18.     fi  
  19.     return $factorial  
  20. }  
  21.   
  22. fact $1  
  23. echo "Factorial of $1 is $?"  
  24.   
  25. exit 0  
(3)递归实现汉诺塔的问题(不使用局部变量的递归)

[cpp] view plaincopy
  1. #汉诺塔算法  
  2. #!/bin/bash  
  3.   
  4. move=0  
  5.   
  6. dohanoi()   
  7. {  
  8.     if [ $1 -eq 0 ]  
  9.     then  
  10.        echo ""   
  11.     else  
  12.         dohanoi "$(($1-1))" $2 $4 $3  
  13.         echo "move $2 ----> $3"  
  14.           
  15.         let "move=move+1"  
  16.   
  17.         dohanoi "$(($1-1))" $4 $3 $2  
  18.     fi  
  19.       
  20.     if [ $# -eq 1 ]  
  21.     then  
  22.         if [ "$(( $1 > 1 ))" -eq 1 ]  
  23.         then  
  24.             dohanoi $1 A C B  
  25.             echo "Total moves  = $move"  
  26.         else  
  27.            echo "The number of disk which you input is illegal! "  
  28.          fi  
  29.     fi  
  30. }  
  31.   
  32. echo "Please input the num of disk:"  
  33. read num  
  34. dohanoi $num 'A' 'B' 'C'  
0 0