• shell浅谈之十函数


    转自:http://blog.csdn.net/taiyang1987912/article/details/39583179

    一、简介

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

    二、详解

    1、函数的定义

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

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

    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)判断当前目录下存在多少个文件和子目录

    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不同)。利用函数参数的传递实现两数的四则运算。

    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不同)。

    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脚本中可以同时放置多个函数,函数之间允许相互调用,而且允许一个函数调用多个函数。

    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关键字来申明局部变量,局部变量将局限在函数范围内。函数可调用函数外的全局变量,若一个局部变量和一个全局变量的名字相同,则在函数中局部变量会覆盖掉全局变量。

    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)使用局部变量进行递归实现阶乘运算,也可采用递推法实现。

    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)递归实现汉诺塔的问题(不使用局部变量的递归)

    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'  


    三、总结

    (1)函数间的相会调用增加了shell编程的灵活性和代码的可重用性,对脚本语言来说很是实用。

    (2)函数的递归调用应进一步理解,阶乘和汉诺塔的实现可逐步分析。

    (3)通过函数可以封装自己的函数库,减少以后开发的难度并使用代码的可重复性

  • 相关阅读:
    1043. 输出PATest(20)
    1042. 字符统计(20)
    1041. 考试座位号(15)
    1040. 有几个PAT(25)
    1035. 插入与归并(25)
    栈:火车进站
    ABC Fennec VS. Snuke
    费解的开关
    最短Hamilton路径
    built?
  • 原文地址:https://www.cnblogs.com/Berryxiong/p/6243327.html
Copyright © 2020-2023  润新知