码迷,mamicode.com
首页 > 系统相关 > 详细

shell编程之函数

时间:2016-07-11 01:37:18      阅读:411      评论:0      收藏:0      [点我收藏+]

标签:shell编程   函数   

函数:function

过程式编程:代码重用;
    模块化编程;
    结构化编程;
    
把一段独立功能的代码当作一个整体,并为之取一个名字;命名的代码段,此即为函数;

函数的定义和使用:
    可在交互式环境下定义函数;
    可将函数放在脚本文件中作为它的一部分;
    可放在只包含函数的单独文件中;
    
    交互式定义函数:(定义在当前shell环境,重启失效)
        #dir() {
        > ls-l
        > }
        
        #dir   #在命令行直接输入函数名dir执行函数;如果函数名与系统命令名字相同,函数优先;
        #unset dir   #取消函数;
        
    可以将经常使用的函数存入函数文件(函数库),需要调用时将函数文件载入shell;
    一旦函数文件载入shell,就可以在命令行或脚本中调用函数;
        加载函数库有两种方式:
            (1)使用点号:
                . /path/to/file.sh
            (2)使用source命令:
                source /path/to/file

    可以使用set命令查看所有已经载入的函数;
    
    若要修改函数,需要先unset取消函数加载,修改后再重新载入shell;

注意:定义函数的代码段不会自动执行,函数只有被调用才会执行;
    所谓调用函数,在代码中给定函数名即可;
    函数名出现的任何位置,在代码执行时,都会被自动替换为函数代码;
    
语法一:
    function f_name {
        函数体
    }

语法二:
    f_name() {
        函数体
    }
    
函数的生命周期:每次被调用时创建,返回时终止;    
    其状态返回结果为函数体中运行的最后一条命令的状态结果;
    自定义状态返回值,需要使用return
        return:
            0:成功
            1-255:失败                
            
给定一个用户名,取得用户的ID号和默认shell;
    #vim f1.sh
    #/bin/bash
    #
    userinfo() {
        if id "$1" &> /dev/null;then
            grep "^$1\>" /etc/passwd | cut -d: -f3,7
        else
            echo "no this user."
        fi
    }
    userinfo $1
    #bash f1.sh root
    #bash f1.sh keith
    
用函数改写服务脚本;
    #!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."
            else
                touch $lockfile
                [ $? -eq 0 ] && echo "start $prog finished."
            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 ;;
        stop)
            stop ;;
        restart)
            stop
            start ;;
        status)
            status ;;
        *)
            usage
            exit 1 ;;
    esac        

函数返回值:
    函数的执行结果返回值:
        (1)使用echo或printf命令进行输出;
        (2)函数体中调用的命令的执行结果;
    函数的退出状态码:
        (1)默认取决于函数体中执行的最后一条命令的退出状态;
        (2)自定义:return;
                    
return命令:
    表示从被调函数返回到主调函数继续执行,返回时可自定义一个返回值;
    用于函数中,常见用法:returen n; n是一个指定的数字,使函数以指定值退出;如果没有指定n值,则返回值是函数体中执行的最后一个命令的退出状态;
    
    return [n]: Return from a shell function.
    
    vim return.sh
    #/bin/bash
    function fun_01 {   #定义一个函数,该函数简单地返回1;
        return 1
    }
    fun_01   #调用该函数;
    echo $?  #查看返回值;
    #bash return.sh
    1
    
local:声明局部变量;
    用于在脚本中声明局部变量,典型的用法是用于函数体内,其作用域在声明该变量的函数体中;
    如果试图在函数体外使用local声明变量,会提示错误;    
        local VAR=value
        
    #vim scope.sh
    #!/bin/bash
    #
    name=tom        #本地变量;
    setname() {
        name=jerry        #这里函数会调用本地变量;
        echo "Function: $name"
    }
    setname
    echo "Shell: $name"
    #bash scope.sh
        Function: jerry
        Shell: jerry
    
    #vim scope.sh
    #!/bin/bash
    #
    name=tom        #本地变量;
    setname() {
        local name=jerry        #局部变量,仅作用于函数体内,不受外部影响;
        echo "Function: $name"
    }
    setname
    echo "Shell: $name"
    #bash scope.sh
        Function: jerry
        Shell: tom
    
函数参数:
    函数可以接受参数;
        在调用函数时,在函数名后面以空白符分隔给定参数列表即可,例如:testfunc arg1 arg2...;
        在函数体当中,可以使用$1,$2...引用传递给函数的参数;还可以在函数中使用$*或$@引用所有参数,$#引用传递的参数的个数;
        
        
    添加10个用户,添加用户的功能使用函数实现,用户名作为参数传递给函数;
        #!/bin/bash
        #
        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 "unknown error."
            fi
        done
    
函数库:
    系统自带的函数库: /etc/init.d/functions;
    
    虽然说functions函数库提供了一些好用的函数,但是仅有这些函数是远远不够的,所以自行开发函数库还是日常工作中很重要的部分;
    
    
函数递归:
    函数调用自身;
    
    阶乘(factorial):
    10!=10*9!=10*9*8!=10*9*8*7!=...
    
    n!=n*(n-1)!=n*(n-1)(n-2)!=...
    
    1!=1
    0!=1
    
    #vim factorial.sh
    #/bin/bash
    #
    fact() {
        if [ $1 -eq 0 -o $1 -eq 1 ];then
            echo 1
        else
            echo $[$1*$(fact $[$1-1])]
        fi    
    }
    fact $1
    
    #bash factorial.sh 10
    3628800
    
    斐波那契数列(Fibonacci sequence):
    1,1,2,3,5,8,13,21,34,...
    
    f(n)=f(n-1)+f(n-2)
    
    #vim fibo.sh
    #!/bin/bash
    #
    fab() {
        if [ $1 -eq 1 -o $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    
    
    #bash fibo.sh 7
    1
    1
    2
    3
    5
    8
    13


shell编程之函数

标签:shell编程   函数   

原文地址:http://keithtt.blog.51cto.com/3080111/1813933

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!