美文网首页shell
shell快讲第六节--shell函数编程

shell快讲第六节--shell函数编程

作者: 梦回上玄 | 来源:发表于2019-08-19 11:45 被阅读0次

    shell快讲第一节--shell基础
    shell快讲第二节--管道与重定向
    shell快讲第三节--正则表达式
    shell快讲第四节--sed与awk
    shell快讲第五节--shell语法基础
    shell快讲第六节--shell函数编程
    shell快讲第七节--shell编程规范与调试
    shell快讲第八节--shell编程实战

    shell函数式编程

    过程式编程

    什么是过程式编程,前面我们看到的脚本都是过程式编程的脚本,它逻辑比较清晰,先执行第一行,再执行第二行,再再执行第三,好处是编写简单,按照步骤写下去就行,坏处也是很明显,如果代码超过100行,别人想读懂或者想改就费劲了,但是自己用着嗨也是可以的。

    函数式编程

    函数式编程从某种程度上解决了代码复用的问题,当代码量大的时候,代码复用,别人阅读你的代码都带来了便捷性,修改的时候也不用担心破坏太多的功能导致调试不方便(bash 是出了名的不方便)

    1、函数语法格式,如下两种格式都是可以的,但是建议使用第一种
    function  name {
    commands
    }
    -----
    name () {
    commands
    }
    
    2、函数的调用

    函数调用,大家可以试下,如果不调用,函数是否会执行,另外函数的调用也是非常简单的,只要敲函数名字即可,对于无参的函数,直接执行。注意函数放在脚本中的位置,如果函数出现在调用命令的后面,那是会报错的

    #!/bin/bash
    function func1 {
        echo "This is an example of a function"
    }
    func1 #调用无参函数
    

    当然还有命令行调用,当然只适合简单的函数:

    >>> function divem { echo $[ $1 * $2 ]; }
    >>> divem 2 3
    
    3、函数参数传递

    shell的参数传递是非常暴力的方式,当然也很有效,函数的参数是我们经常会用到的,正如上面的例子是无参的函数,下面看下有参的函数

    #!/bin/bash
    function badfunc1 {
        echo $[ $1 * $2 ] #$1 就是第一个变量 $2就是第二个变量,shell函数不会检查参数个数,这个一定要注意
    }
    badfunc1 2 4 #注意体会下参数传递
    

    上面讲了字符串的传递,下面看下数组的传递,毕竟shell里面除了字符串就只有数组这两个数据类型了,当然这个数字传递我觉得有点超纲,为啥呢,因为shell根本不支持数组传递,但是我们可以通过技巧来解决这个问题,既然是技巧了,我觉得还是不掌握的好。意义不大。

    #!/bin/bash
    # array variable to function test
    function testit {
            local newarray #local定义局部变量
            newarray=`echo "$@"`
            echo "The new array value is: ${newarray[*]}"
    }
    myarray=(1 2 3 4 5)
    echo "The original array is ${myarray[*]}"
    testit ${myarray[*]}
    
    4、脚本的参数传递

    ​ 函数的参数传递和脚本的参数传递不是一回事,但是传递的方法是类似的,讲到了参数传递,那么就来看下脚本的参数传递,shell的参数传递还是很粗糙的

    #!/bin/bash
    #test.sh
    function badfunc1 {
        echo $[ $1 * $2 ] #这里是函数里的$1 $2
    }
    badfunc1 $1 $2 #这里的$1 $2 和上面的$1 $2并不一样
    
    >>> ./test.sh 2 3 #这是调用方法
    
    5、函数的返回值

    ​ 任何一门语言的函数都有返回值,但是偏偏shell的函数的返回值处理最为奇葩,它直接返回的只有状态码,任何数据类型的返回值得用echo打印,但是我们既然学的是shell,当然就得熟悉这种传值的方法,看下面例子:

    #!/bin/bash
    # testing the exit status of a function
    func1() {
        echo "trying to display a non-existent file"
        ls -l badfile
    }
    echo "testing the function: "
    func1 #调用函数
    echo "The exit status is: $?" #这里$2是返回上一行命令的状态码
    

    ​ 我们看到了上面默认函数只能传递出状态码,状态码一般会默认,但是我们可以通过return主动抛,不过这并不实用,这里大家知道就好,因为状态码0-255,过了这个数值它就没用了,return的意愿就不大了。

    #!/bin/bash
    # using the return command in a function
    function dbl {
        read -p "Enter a value: " value
        echo "doubling the value"
        return $[ $value * 2 ]
    }
    dbl #调用函数
    echo "The new value is $?"
    


    ​ 下面我们来看点有意义的,就是字符串传递了,这样的传出的值就可以超过255了,shell是弱数据类型,数字和字符串传递方法一样,数字需要使用[]进行计算

    #!/bin/bash
    # using the echo to return a value
    function dbl {
        read -p "Enter a value: " value
        echo $[ $value * 2 ]
    }
    result=$(dbl)  #注意了,这里不是简单的函数调用,而是函数调用+接收echo传出的值,$(dbl)等价`dbl`
    #result=`dbl`
    echo "The new value is $result"
    
    6、变量及变量作用域

    ​ 之前我们讲了参数的传递,参数也是一种变量,但是它更多的值传递,而这里我们要将的是变量传递,变量分为全局变量和局部变量。

    局部变量 顾名思义就是在局部生效的变量,它的生效范围就是函数内部,函数外部调用是无效的,局部变量就是的关键字就是local,不用local关键字就是全局变量,当然有一个更好的解决办法,就是不要让局部变量和全局变量重名。

    #!/bin/bash
    # demonstrating a bad use of variables
    function func1 {
        temp=$[ $value + 5 ]
        result=$[ $temp * 2 ]
    }
    temp=4
    value=6
    func1
    echo "The result is $result"
    if [ $temp -gt $value ]
    then
        echo "temp is larger"
    else
        echo "temp is smaller"
    fi
    ###################下一个脚本######################
    #!/bin/bash
    # demonstrating the local keyword
    function func1 {
        local temp=$[ $value + 5 ]
        result=$[ $temp * 2 ]
    }
    temp=4
    value=6
    func1
        echo "The result is $result"
    if [ $temp -gt $value ]
    then
        echo "temp is larger"
    else
        echo "temp is smaller"
    fi
    
    7、脚本的退出码

    ​ 前面讲到了函数的退出码,实际上函数的退出码确实不怎么重要,重要的是脚本的退出码,在多个脚本联动的时候(比如A脚本调用B脚本)那么B脚本失败了,我们就只能根据退出码判断失败了,如果我们能主动指定退出码,就能判断为啥失败,退出码使用的命令exit

    #!/bin/bash
    
    #1112rundeck.sh 无参
    #date:2019.01.24
    #doc:1为系统错误,2为文件不存在或者权限错误,3为未知错误
    cd ../app
    docker stack deploy -c app-stack.yml fhcdn
    if [ $? -ne 0 ];then
        echo -e "\033[31m\033[01m error:安装app失败 \033[0m"
        exit 1
    fi
    
    

    相关文章

      网友评论

        本文标题:shell快讲第六节--shell函数编程

        本文链接:https://www.haomeiwen.com/subject/malssctx.html