bash腳本----case和function



case語句

 什麼時候用到case?

   當多次判斷變量是否屬於某個字符串時候


case語句的語法格式:

        case  $VARAIBLE  in  

         PAT1) 注:如果PAT1匹配到$VARAIBLE時候,執行分支1 同理

                  分支1

        ;; 注:每一個判斷條件都要雙分號,同理

        PAT2)   

             分支2

        ;;

        ...

        *)  都不屬於以上情況,執行分支n

           分支n

        ;;

       esac   最後一個不需要



 特性:case支持glob風格的通配符:


       *:任意長度的任意字符;

       ?:任意單個字符;

      []:範圍內任意單個字符;

       a|b:a或b;



case簡單示例:寫一個服務框架腳本;


  (1) 此腳本可接受start, stop, restart, status四個參數之一;

  (2) 如果參數非此四者,則提示使用幫助後退出;

  (3) start,則創建lockfile,並顯示啓動;stop,則刪除lockfile,並顯示停止;restart,則先刪  除此文件再創建此文件,而後顯示重啓完成;status,如果lockfile存在,則顯示running,否則,則顯示爲stopped.


     

 #!/bin/bash
      #
      # chkconfig: - 50 50  注:定義運行級別、啓動優先級、關閉優先級
     # description: test service script  注:描述信息
     #
         prog=$(basename $0)  注:以變量替換的方式取路徑基名,並賦值給變量prog
         lockfile=/var/lock/subsys/$prog 注:給變量lockfile賦值一個文件路徑
        case $1  in
        start) 
              if [ -f $lockfile ]; then   注:-f進行文件存在性測試
                 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 "start $prog finished."
            fi
          ;;
        status)
                if [ -f $lockfile ]; then
                    echo "$prog is running"
                else
                     echo "$prog is stopped."
                fi
          ;;
        *)
            echo "Usage: $prog {start|stop|restart|status}"
            exit 1
        esac




函數:function 


  爲什麼要用到函數?

    爲了簡化自己寫的代碼量,重複多次使用的功能可以包裝成函數多次調用。也會使你的代碼更有結構

    


什麼是函數?

   把一段獨立功能的代碼當作一個整體,併爲之一個名字;命名的代碼段,此即爲函數;



怎樣使用函數?

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

  函數名出現的任何位置,在代碼執行時,都會被自動替換爲函數代碼;函數的生命週期:每次被調用時創建,返回時終止;

                語法一:

                        function  f_name  {

                                ...函數體...

                                            }

                語法二:

                        f_name()  {

                                ...函數體...

                                    }



自定義狀態返回值方法:

    其狀態返回結果爲函數體中運行的最後一條命令的狀態結果;

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

        return [0-255]

        0: 成功

        1-255: 失敗



函數的執行結果返回值:

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

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


&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

函數使用舉例1:給定一個用戶名,取得用戶的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
            username=$2
            userinfo


&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

函數使用舉例2:服務腳本框架

           

 #!/bin/bash
            #
            # chkconfig: - 50 50
            # description: test service script
      
            prog=$(basename $0)
            lockfile=/var/lock/subsys/$prog
        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
                }
        status() {
                if [ -f $lockfile ]; then
                    echo "$prog is running"
                else
                    echo "$prog is stopped."
                fi
                    }
        usage() {
                    echo "Usage: $prog {start|stop|restart|status}"
                }
        case $1 in
        start)  
                start ;;  注:調用start函數,以下同理
        stop)
                stop ;;
        restart)
                stop
                start ;;
        status)
                status ;;
            *)
                    usage
        exit 1 ;;
                    esac


&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

函數可以接受參數:


     1.在函數體中當中,可以使用$1,$2, ...引用傳遞給函數的參數;

     2.還可以函數中使用$*或$@引用所有參數,

     3. $#引用傳遞的參數的個數;     

      例如,testfunc  arg1 arg2 arg3 ...

       注:在調用函數時,在函數名後面以空白符分隔給定參數列表即可


示例:添加10個用戶,



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



函數可以接受參數舉例1

               

 #!/bin/bash
                #
                # 5: user exists
                addusers() {
                        if id $1 &> /dev/null; then
                                return 5
                        else
                            useradd $1
                            retval=$?
                            return $retval
                            fi
                            }
                for i in {1..10}; do
                        addusers ${1}${i}
                        retval=$?
                    if [ $retval -eq 0 ]; then
                            echo "Add user ${1}${i} finished."
                    elif [ $retval -eq 5 ]; then
                            echo "user ${1}${i} exists."
                    else
                            echo "Unkown Error."
                     fi
                     done


&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

練習:寫一個腳本;

使用函數實現ping一個主機來測試主機的在線狀態;主機地址通過參數傳遞給函數;

主程序:測試172.16.1.1-172.16.67.1範圍內各主機的在線狀態;

練習:寫一個腳本;

打印NN乘法表;

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&




變量作用域




局部變量:作用域是函數的生命週期;在函數結束時被自動銷燬;

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

本地變量:作用域是運行腳本的shell進程的生命週期;因此,其作用範圍爲當前shell腳本程序文件;

變量作用域舉例1

            #!/bin/bash
            #
                name=tom
            setname() {
                local name=jerry
                echo "Function: $name"
                        }
                setname
                echo "Shell: $name"





函數遞歸

函數直接或間接調用自身;

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

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

函數遞歸舉例1

                

    #!/bin/bash
                    #
                    fact() {
                        if [ $1 -eq 0 -o $1 -eq 1 ]; then
                      echo 1
                         else
                           echo $[$1*$(fact $[$1-1])]
                          fi
                            }
                        fact $1




函數遞歸舉例2

                  1,1,2,3,5,8,13,21,...

               

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




&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

編外擴展

示例1:顯示一個菜單給用戶;

cpu) display cpu information

mem) display memory information

disk) display disks information

quit) quit

要求:(1) 提示用戶給出自己的選擇;

   (2) 正確的選擇則給出相應的信息;否則,則提示重新選擇正確的選項;

   

#!/bin/bash
#
cat << EOF
cpu) display cpu information
mem) display memory infomation
disk) display disks information
quit) quit
===============================
EOF
read -p "Enter your option: " option
while [ "$option" != "cpu" -a "$option" != "mem" -a                                
"$option" != "disk" -a "$option" != "quit" ]; do
echo "cpu, mem, disk, quit"
read -p "Enter your option again: " option
done
if [ "$option" == "cpu" ]; then
lscpu
elif [ "$option" == "mem" ]; then
free -m
elif [ "$option" == "disk" ]; then
fdisk -l /dev/[hs]d[a-z]
else
echo "quit"
exit 0
fi



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章