Function函數實例

函數:function

    把一段獨立功能的代碼當做一個整體,而后為之取一個名字,命令的代碼段,即為函數。

注意:

    定義函數的代碼段不會自動執行,在調用時執行;所謂調用函數,在代碼中給定函數名即可

    函數名出現的任何位置,在代碼執行時,都會被自動替換為函數代碼;


過程式編程語言:代碼重用即可用到函數

    模塊化編程

    結構化編程


函數使用語法:

    語法一:

    function f_name{

    ..函數體

    }

    

    語法二:

    f_name() {

             …函數代碼(函數體)

    }

函數的生命周期:

    每次被調用時創建,返回時終止; 

    其狀態返回結果為函數體中運行的最后一條命令的狀態結果

    自定義狀態返回值,需要使用:return

        return:[0-255]

            0:成功

            1-255:失敗


示例:給定一個用戶名:取得用戶的ID號和默認shell

    #!/bin/bash
    #
    userinfo() {
    if id "$username" &> /dev/null;then
        grep "^$username\>" /etc/passwd | cut -d: -f3,7
    else
        echo "no such user"
    fi
    }
    username=$1
    userinfo

 

   示例2:服務腳本框架

    #!/bin/bash
    #模擬創建文件來模擬服務的啟動、停止、重啟、狀態等。
    prog=$(basename $0)   //將此此腳本文件名當做創建的文件   
    lockfile=/var/lock/subsys/$prog   //函數調用來將腳本文件名創建到/var/lock/subsys/下
    
    ######定義函數、創建文件模擬啟動服務###############
    start(){
            if [ -f $lockfile ];then
                echo "$prog is running yet"
            else
                touch $lockfile
                [ $? -eq 0 ] && echo "start $prog finshed"
            fi
    }
    
    ######定義函數、刪除文件模擬停止服務###############
    stop(){
            if [ -f $lockfile ];then
                rm -f $lockfile
                [ $? -eq 0 ] && echo "stop $prog finished"
            else
                echo "$prog is not running"
            fi
    }
    
    ######定義函數、刪除文件在創建文件模擬重啟服務#######
    restart (){
            if [ -f $lockfile ];then
                rm -f $lockfile
                touch $lockfile
                echo "restart $prog finished"
            else
                touch -f $lockfile
                echo "restart $prog finnished"
            fi
    }
    
    ######定義函數、查看文件模擬查看服務狀態###############
    status() {
            if [ -f $lockfile ];then
                echo "$prog is running" 
            else
                echo "$prog is stopped"
            fi
    }
    
    
    #######定義函數、指定使用方法使用方法##########
    usage() {
            echo "Usage: $prog {start|stop|restart|startus}"
    }
    
    
    ######用case多分支條件語句來進行函數調用#########
    case $1 in    //$1為用戶運行此腳本指定參數來進行調用函數。  
        start)    //如果傳遞參數為start,則調用相對應的start函數。
            start ;;
        stop)
            stop
            ;;
        restart)
            stop
            start
            ;;
        status)
            status
            ;;
        *)
            usage
            exit 1 ;;
    esac

函數的返回值:

    函數的執行結果返回值

    函數名出現的地方能夠顯示代碼執行結果

    (1)使用echo或printf命令進行輸出

    (2)函數體中調用的命令的執行結果 

函數的退出狀態碼:

    (1)默認取決于函數體中執行的最后一條命令的退出狀態碼

    (2)自定義:return

函數可以接受參數

      傳遞參數給函數時,在函數體中,可以使用$1,$2,…..,引用傳遞給函數的參數;還可以使用$*、$@引用所有參數,$#引用傳遞的參數的個數

      在調用函數時,在函數名后面可以以空白符分割給定參數列表即可,列如,testfunc  arg1 arg2  arg3….   (注意,testfunc 是函數名,arg1 arg2  arg3 是調用函數是傳遞參數)

示例:添加10個用戶

    添加用戶的功能使用函數實現,用戶名做為參數傳遞給函數

#!/bin/bash
#
#5:user exists    //說明5代表的含義
#####定義函數,功能:創建用戶###########
addusers() {    
    if id $1 &> /dev/null;then
        return 5       //如果if判斷語句為假,則表示用戶存在則不創建,并指定函數返回值為5
    else
        useradd $1
        retval=$?     //創建用戶成功時將返回值保存到變量中,然后在用return命令返回其值。
        return $retval   //注意,如果不用變量保存其返回值,則在下方調用時不能更準確的判定其是否成功。因為狀態返回值是其上一條代碼的執行結果返回值。
    fi
}


######使用for循環語句來循環創建用戶#################
for i in {1..10};do    
    addusers ${1}${i}   //調用函數,創建指定參數的用戶1到10,
    retval=$?   //保存指定的函數值   
    if [ $retval -eq 0 ];then    //判斷其返回值來輸出創建狀態,如果為0,則表示創建成功
        echo "Add user ${1}${i} finished"   
    elif [ $retval -eq 5 ];then      //判斷其返回值來輸出創建狀態,如果為5,則表示其用戶存在,在函數體中,我們自己定義了用戶存在的函數返回值,如果用戶存在,則不會執行創建命令,也就不會生成返回值為0,所以其狀態返回值只賦值過一次,就是用戶存在時的返回值。
        echo "user exist" 
    else
        echo "Unkown Error"
         fi  
done

復習

變量作用域:

    函數為代碼引入了一個獨立新的作用域,在函數內部存在,有效作用范圍只在函數內部。

局部變量:

    作用域是函數的生命周期,在函數結束時被自動銷毀

    定義局部變量的方法:local VAR=VALUE

本地變量:

    作用域是腳本的聲明周期;

    作用域是運行腳本的shell進程的生命周期。如果沒有在腳本中銷毀,則腳本的shell進程結束則變量銷毀



示例:本地變量和局部變量的區別

[root@CentOs6 tmp]# vim BianLiang.sh 
#!/bin/bash
#
name=tom     //腳本內有個name變量,其值為tom
setname() {       // 定義函數
    local name=jerry   
    //定義于其腳本變量相同名的變量,其值為jerry,其中local為定義為局部變量。
#設置局部變量之后,此函數內的變量不會影響到調用它的腳本中的變量。
    echo "Function: $name"  //輸出函數內name變量值
}
setname    //調用函數
echo "shell:$name"    輸出name變量值,下面觀察一下效果

#############運行腳本,此時函數輸出變量和腳本輸出變量各為其自有的,因為我們把函數體內的變量設置為了局部變量,局部變量作用范圍為其函數體代碼段。############
[root@CentOs6 tmp]# bash BianLiang.sh 
Function: jerry
shell:tom


將函數體內的local去掉
#############運行腳本,此時函數輸出變量和腳本輸出變量為相同,因為現在函數體內的變量為本地變量,即會影響到當前shell及其腳本中的變量,因為此時函數體內的內容替換到調用的位置之后就相當于再一次為給其相同名的變量(name)重新賦值,所有輸出結果為相同(當然這也跟輸出變量的位置有關)############
[root@CentOs6 tmp]# bash BianLiang.sh 
Function: jerry
shell:jerry

函數遞歸:

    函數直接或間接調用自身

示例:

 階乘:10的階乘

    10!=10*9!=10*9*8!=10*9*8*7!=…..

     n!=n*(n-1)!=n*(n-1)*(n-2)!=……

    10!=10*(10-1)!=10*(10-1)*(10-2)=….

[root@CentOs6 tmp]# cat JieChen.sh 
#!/bin/bash
#
fact () {
if [ $1 -eq 0 -o $1 -eq 1 ];then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}
fact $1

斐波切數列:

1.1.2.3.5.8.13.21….n-1+n-2

$[$(fab $[$1-1])+$(fab $[$1-2])]

#!/bin/bash
#
fab () {
if [ $1 -eq 1 ];then
echo 1
elif [ $1 -eq 2 ];then
echo 1
else
echo $[$(fab $[$1-1])+$(fab $[$1-2])]  
fi
}
for i in `seq 1 $1`;do
fab $i
done

原創文章,作者:Lii,如若轉載,請注明出處:http://www.www58058.com/38162

(0)
LiiLii
上一篇 2016-08-21 20:46
下一篇 2016-08-21 20:46

相關推薦

  • 用“逐步排除”的方法定位Java服務線上“系統性”故障

    一、摘要 由 于硬件問題、系統資源緊缺或者程序本身的BUG,Java服務在線上不可避免地會出現一些“系統性”故障,比如:服務性能明顯下降、部分(或所有)接口超 時或卡死等。其中部分故障隱藏頗深,對運維和開發造成長期困擾。筆者根據自己的學習和實踐,總結出一套行之有效的“逐步排除”的方法,來快速定位Java 服務線上“系統性”故障。 二、導言 Java 語言是廣…

    2015-02-28
  • OpenStack私有云部署

    架構 實驗環境 角色 主機名 網卡 系統環境 Controller?Node controller.qween.com 管理接口eth0:192.168.22.128 外部接口eth1:192.168.36.130CentOS6.8Compute Nodecompute1.qween.com管理接口eth0:192.168.22.129 隧道接口eth1:1…

    2017-12-12
  • 基礎指令的使用篇2 Linux版

    #echo -e "\033[41;33:4:5m"\033[0m] man命令 /usr/share/man 地址 whatis passwd 查看passwd的man 章節 man n passwd 顯示passwd的第幾章man文件 man -a passwd 列出所有的章節     -f   &nbs…

    Linux干貨 2016-08-04
  • CentOS進程管理

    CentOS進程管理 筆記 Linux系統中的基本運行單位是進程,通過對系統系統中的進程的管理能夠對系統的實時運行狀態進行了解和調度。Linux中提供了用于查看、調整和停止進程的命令。本文仍然以RHEL6說明Linux系統的進程管理。 CentOS進程管理 一、進程概述 二、查看進程 1、使用ps命令 2、top命令 一、進程概述 程序是保存在存儲介質中的可…

    Linux干貨 2017-05-15
  • N25-第十二周博客作業

    1、請描述一次完整的http請求處理過程; (1) 建立或處理連接:接收請求或拒絕請求;(2) 接收請求:接收來自于網絡上的主機請求報文中對某特定資源的一次請求的過程;(3) 處理請求:對請求報文進行解析,獲取客戶端請求的資源及請求方法等相關信息;(4) 訪問資源:獲取請求報文中請求的資源;從磁盤中獲取(5) 構建響應報文:(6) 發送響應報文:(7) 記錄…

    Linux干貨 2017-04-09
  • DNS高級應用之ACL和View

    一、環境準備:     1、準備三臺主機,要求如下      (1) DNS服務器雙網卡:eth0:192.168.10.203  eth1: 172.16.2.10       (2)測試機1雙網卡: eth0: 172.16.…

    Linux干貨 2015-06-01

評論列表(1條)

  • 馬哥教育
    馬哥教育 2016-08-21 22:02

    函數通過先定義,然后通過函數名來進行調用,同時他實現了代碼重用和效率提高,這是一個很重要的shell編程思想,需要多寫,多練。

欧美性久久久久