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