zoukankan      html  css  js  c++  java
  • shell脚本编程-函数

    一、函数的定义和调用

    二、函数的返回值

    三、带参数的函数

    四、自定义函数库

    五、functions函数库

    六、递归函数

    一、函数的定义和调用

      函数是Shell脚本中自定义的一系列执行命令,一般来说函数应该设置返回值.

      语法:

    #shell中的函数定义
    #其中function为关键字,FUNCTION_NAME为函数名
    funciton FUNCTON_NAME(){
      command1 #函数体中可以有多个语句,不允许有空语句
      command2
      ...
    }
    #省略关键字function,效果一样
    FUNCTION_NAME(){
      command1
      command2
      ...
    }

      eg:

     1 [rhat@localhost shell]$ vim sayHello.sh
     2 #!/bin/bash
     3 function sayHello(){
     4     echo "Hello"
     5 }
     6 echo "Call function sayHello"
     7 sayHello
     8 [rhat@localhost shell]$ sh ./sayHello.sh 
     9 Call function sayHello
    10 Hello

      or

     1 [rhat@localhost shell]$ vim countLine.sh
     2 #!/bin/bash
     3 FILE=/etc/passwd
     4 function countLine(){
     5     local i=0
     6     while read line
     7     do
     8         let ++i
     9     done < $FILE
    10     echo "$FILE have $i lines"
    11 }
    12 echo "Call function countLine"
    13 countLine
    14 #执行结果
    15 [rhat@localhost shell]$ sh ./countLine.sh 
    16 Call function countLine
    17 /etc/passwd have 31 lines

     二、函数的返回值

      函数的返回值又叫函数的返回状态,实际上是一种通信方式.获取上一个命令返回值得方式是使用$?

      eg:

     1 [rhat@localhost shell]$ vim checkFileExist.sh
     2 #!/bin/bash
     3 FILE=/etc/notExistFile
     4 function checkFileExist(){
     5     if [ -f $FILE ];then
     6         return 0
     7     else
     8         return 1
     9     fi
    10 }
    11 echo "Call function checkFileExist"
    12 checkFileExist    #调用函数
    13 if [ $? -eq 0 ];then
    14     echo "$FILE exist"
    15 else
    16     echo "$FILE not exist"
    17 fi
    18 #执行结果
    19 [rhat@localhost shell]$ sh ./checkFileExist.sh 
    20 Call function checkFileExist
    21 /etc/notExistFile not exist

      or

     1 [rhat@localhost shell]$ vim checkNum.sh 
     2 #!/bin/bash
     3 function checkNum(){
     4     echo -n "Please input a number:"
     5     read NUM
     6     if [ $NUM -ge 0 -a $NUM -lt 10 ];then
     7         return 0
     8     fi
     9     if [ $NUM -ge 10 -a $NUM -lt 20 ];then
    10         return 1
    11     fi
    12     if [ $NUM -ge 20 -a $NUM -lt 30 ];then
    13         return 2
    14     fi
    15     return 3
    16 }
    17 echo "Call function checkNum"
    18 checkNum
    19 RTV=$?
    20 if [ $RTV -eq 0 ];then
    21     echo "The number is between[0,10]"
    22 elif [ $RTV -eq 1 ];then
    23     echo "The number is between[10,20]"
    24 elif [ $RTV -eq 2 ];then
    25     echo "The number is between[20,30]"
    26 else
    27     echo "Unknown input"
    28 fi
    29 #执行结果
    30 [rhat@localhost shell]$ sh ./checkNum.sh 
    31 Call function checkNum
    32 Please input a number:30
    33 Unknown input

    三、带参数的函数

      向函数传递参数是使用位置参数来实现的.

     1 [rhat@localhost shell]$ vim checkFileExist_v2.sh 
     2 #!/bin/bash
     3 function checkFileExist(){
     4     if [ -f $1 ];then
     5         return 0
     6     else
     7         return 1
     8     fi
     9 }
    10 echo "Call function checkFileExist"
    11 checkFileExist $1
    12 if [ $? -eq 0 ];then
    13     echo "$FILE exist"
    14 else
    15     echo "$FILE not exist"
    16 fi
    17 #执行结果.
    18 [rhat@localhost shell]$ sh ./checkFileExist_v2.sh haha.txt
    19 Call function checkFileExist
    20  not exist

      or

     1 [rhat@localhost shell]$ vim power.sh
     2 #!/bin/bash
     3 function power(){
     4     RESULT=1
     5     LOOP=0
     6     while [[ "$LOOP" -lt $2  ]]
     7     do
     8         let "RESULT=RESULT*$1"
     9         let "LOOP+=1"
    10     done
    11     echo $RESULT
    12 }
    13 echo "Call function power with parameters"
    14 power $1 $2
    15 #执行结果
    16 [rhat@localhost shell]$ sh ./power.sh 3 3
    17 Call function power with parameters
    18 27

      除了在脚本运行时给脚本传入位置参数外,还可以使用内置命令set命令给脚本指定位置参数的值.(又叫重置)

     1 [rhat@localhost shell]$ vim set01.sh 
     2 #!/bin/bash
     3 set 1 2 3 4 5 6
     4 COUNT=1
     5 for i in $@
     6 do 
     7     echo "Here $$COUNT is $i"
     8     let "count++"
     9 done
    10 #执行结果
    11 [rhat@localhost shell]$ sh ./set01.sh a b c d e f 
    12 Here $1 is 1
    13 Here $1 is 2
    14 Here $1 is 3
    15 Here $1 is 4
    16 Here $1 is 5
    17 Here $1 is 6

      在shell中使用shift命令移动位置参数.shift命令可以让位置参数左移一位.

     1 [rhat@localhost shell]$ vim shift03.sh
     2 #!/bin/bash
     3 until [ $# -eq 0 ]
     4 do
     5     echo "Now $i is :$1,total parameter is:$#"
     6     shift #加数字 2 表示 左移2个参数,eg: shift 2
     7 done
     8 #执行结果
     9 [rhat@localhost shell]$ sh ./shift03.sh 1 2 3 a v c
    10 Now $i is :1,total parameter is:6
    11 Now $i is :2,total parameter is:5
    12 Now $i is :3,total parameter is:4
    13 Now $i is :a,total parameter is:3
    14 Now $i is :v,total parameter is:2
    15 Now $i is :c,total parameter is:1

    四、自定义函数库

      对某些很常用的功能,必须考虑将其独立出来,集中存放在一些独立的文件中,这些文件就称为”文件库“,在实践中建议库函数使用下划线开头.

      eg:lib01.sh 函数库.

    1 [rhat@localhost shell]$ vim lib01.sh
    2 _checkFileExist(){
    3     if [ -f $1 ];then
    4         echo "File:$1 exist"
    5     else
    6         echo "File:$1 not exist"
    7 }

      加载函数库的两种方式:

    1 #使用”点“.命令。
    2 [rhat@localhost shell]$ . ./lib01.sh      # / 前面的.表示当前目录,,别搞混。
    3 #使用source命令。
    4 [rhat@localhost shell]$ source ./lib01.sh 

      脚本中调用函数库.

    1 [rhat@localhost shell]$ vim callLib01.sh
    2 #!/bin/bash    
    3 source ./lib01.sh            #引用函数库到当前shell.
    4 _checkFileExist /etc/notExistFile
    5 _checkFileExist /etc/passwd
    6 #执行结果
    7 [rhat@localhost shell]$ sh ./callLib01.sh 
    8 File:/etc/notExistFile not exist
    9 File:/etc/passwd exist

    五、函数库/etc/init.d/functions简介

      很多Linux发行版中都有/etc/init.d目录,这是系统中放置所有开机启动脚本的目录,这些开机脚本在脚本开始运行时都会加载/etc/init.d/functions 或/etc/rc.d/init.d/functionshanshuku.(两个库内容实际上完全一样. 如下:

    1 # Source functions library
    2  . /etc/init.d/functions
    3 或者
    4 # Source functions library
    5 . /etc/rc.d/init.d/functions

      在脚本中使用functions函数库.

     1 [rhat@localhost shell]$ vim callFunctions01.sh
     2 #!/bin/bash
     3 source /etc/init.d/functions
     4 confirm ITEM    #confirm 实际上是functions库中的一个函数功能.
     5 if [[ $? -eq 0 ]];then
     6     echo "ITEM confirmed"
     7 else
     8     echo "ITEM not confirmed"
     9 fi
    10 #执行结果.
    11 [rhat@localhost shell]$ sh ./callFunctions01.sh 
    12 Start service ITEM (Y)es/(N)o/(C)ontinue? [Y] y
    13 ITEM confirmed

      functions库中常用的函数:

    checkpid() 检查某个PID是否存在
    daemon() 以deamon方式启动某个服务
    killproc() 停止某个进程
    pidfileofproc() 检查某个进程的PID文件
    pidofproc() 检查某个进程的PID
    status() 判断某个服务的状态
    echo_success() 打印OK
    echo_failure() 打印FAILED
    echo_passed() 打印PASSED
    echo_warning() 打印WARNING
    success() 打印OK并记录日志
    failure() 打印FAILED并记录日志
    passed() 打印PASSED并记录日志
    warning() 打印WARNING并记录日志
    action() 执行给定的命令,并根据执行结果打印信息
    strstr() 检查$1字符串中是否含有$2字符串
    confirm() 提示是否启动某个服务.

     六、递归函数

      在函数中继续调用函数自身,注意调用条件,否则会毫无止境的调用,语法:

    function recursion(){
            recursion
            confitionThatEndTheRecursion    #停止递归的条件.
    }

      例如阶乘函数:n!=1x2x3x4x...xn.

     1 [rhat@localhost shell]$ cat factorial01.sh 
     2 #!/bin/bash
     3 function factorial01(){
     4     local NUMBER=$1
     5     if [ $NUMBER -le 0 ];then
     6         RES=1
     7     else
     8         factorial01 $((NUMBER-1))
     9         TEMP=$RES
    10         NUMBER=$NUMBER
    11         RES=$((NUMBER*TEMP))
    12     fi
    13 }
    14 factorial01 $1
    15 echo $RES
    16 #执行结果
    17 [rhat@localhost shell]$ sh -x ./factorial01.sh 4 #-x为观察执行过程的细节.
    18 + factorial01 4
    19 + local NUMBER=4
    20 + '[' 4 -le 0 ']'
    21 + factorial01 3
    22 + local NUMBER=3
    23 + '[' 3 -le 0 ']'
    24 + factorial01 2
    25 + local NUMBER=2
    26 + '[' 2 -le 0 ']'
    27 + factorial01 1
    28 + local NUMBER=1
    29 + '[' 1 -le 0 ']'
    30 + factorial01 0
    31 + local NUMBER=0
    32 + '[' 0 -le 0 ']'
    33 + RES=1
    34 + TEMP=1
    35 + NUMBER=1
    36 + RES=1
    37 + TEMP=1
    38 + NUMBER=2
    39 + RES=2
    40 + TEMP=2
    41 + NUMBER=3
    42 + RES=6
    43 + TEMP=6
    44 + NUMBER=4
    45 + RES=24
    46 + echo 24
    47 24

      linux shell 汉诺塔实现:我没理解得了.((~﹃~)~zZ)

     1 [rhat@localhost shell]$ vim hanoi01.sh
     2 #!/bin/bash
     3 function hanoi01(){
     4     local num=$1
     5     if [ "$num" -eq "1" ]; then
     6         echo "Move:$2---->$4"
     7     else
     8         hanoi01 $((num-1)) $2 $4 $3
     9         echo "Move:$2---->$4"
    10         hanoi01 $((num-1)) $3 $2 $4
    11     fi
    12 }
    13 hanoi01 4 A B C
    14 #执行结果
    15 [rhat@localhost shell]$ sh ./hanoi01.sh 
    16 Move:A---->B
    17 Move:A---->C
    18 Move:B---->C
    19 Move:A---->B
    20 Move:C---->A
    21 Move:C---->B
    22 Move:A---->B
    23 Move:A---->C
    24 Move:B---->C
    25 Move:B---->A
    26 Move:C---->A
    27 Move:B---->C
    28 Move:A---->B
    29 Move:A---->C
    30 Move:B---->C

      嵌套函数天生的结构就注定了其晦涩的可读性,在不少大公司内部的开发规范中也明确规定了不允许使用递归,所以在实际工作中药尽量避免使用递归.

    返回顶部

  • 相关阅读:
    微信小程序开发之初探
    C# 利用SharpPcap实现网络包捕获嗅探
    C# SharpMap的简单使用
    C# 实现中国象棋【棋盘,棋子】
    C# 实现FTP客户端
    C# 实现连连看功能
    C# 实现截图软件功能
    C# 利用PrintDocument定制打印单据
    驰骋工作流引擎设计系列05 启动流程设计
    驰骋工作流引擎设计系列04 流程引擎表结构的设计
  • 原文地址:https://www.cnblogs.com/xccnblogs/p/4842259.html
Copyright © 2011-2022 走看看