Linux Shell:Shell函数使用

作者: xiaogp | 来源:发表于2021-09-06 10:37 被阅读0次

    摘要:LinuxShell

    函数语法

    函数就是将一组重复使用Shell语句组合起来一起调用,这样可以省略代码量,类似于alias命令给长shell命令设置别名,不一样的是alias不能传参,而Shell函数可以传参,Shell函数的格式如下

    函数名() {
        代码块
    }
    

    也可以显式申明为function关键字

    function 函数名() {
        代码块
    }
    

    函数调用

    函数的调用直接调用函数名和参数,不要要调用$()

    (1)函数传参

    函数传参不需要在函数开头的函数名()的括号中指定参数名甚至类型,圆括号中不需要任何元素,在代码块内部调用$+数字获得入参,相当于函数入参是一个数组,因此对顺序有要求,当参数的位次数大于等于10个以上时需要用${}括起来,这个用法只在函数内生效,和Shell脚本传参的$+数字互不影响

    #!/bin/bash
    
    my_func() {
        echo $0
        echo $1
        echo $2
        echo $#
    }
    
    my_func a b
    

    运行脚本结果如下,可见函数入参是从位置1开始的$1,而0还是代表脚本名。`#`是函数入参个数

    root@ubuntu:~/Shell# bash test.sh
    test.sh
    a
    b
    2
    

    如果入参是数组形式,也可以使用$n或者循环迭代获取数组元素

    #!/bin/bash
    
    my_func() {
        value=1
        for i in $@
        do
                value=$[$value * $i]
        done
        echo $value
    }
    
    array=(5 2 3)
    res=`my_func ${array[@]}`
    echo $res
    

    运行脚本

    root@ubuntu:~/Shell# bash test.sh
    30
    
    (2)返回值处理

    函数的返回值有两种用法:

    • 返回0~255中的一个整数:函数内使用return + 整数,调用函数结果使用$?
    • 返回自定义字符串:函数内使用echo返回值,调用函数使用``获得$()当做命令执行赋给新变量

    第一种情况使用return关键字

    #!/bin/bash
    
    my_func() {
        return 3
    }
    
    my_func
    res=$?
    echo $res
    
    bash test.sh  # 3
    

    如果return的值超过255,比如256则实际return的值由从0开始滚动,如果return的值不是整数,则会直接报错

    return: a: numeric argument required
    

    第二种情况使用echo关键字

    #!/bin/bash
    
    my_func() {
        echo $[$1 * 10]
    }
    
    res=`my_func 10`
    echo $res
    
    bash test.sh  # 100
    
    (3)没有返回值

    没有返回值通常是代码块内部完成了某个命令,比如

    #!/bin/bash
    
    my_func() {
        /opt/anaconda3/bin/python job.py $1
    }
    
    my_func job1
    my_func job2
    my_func job3
    echo '所有任务完成!'
    

    将一个带有参数的任务包装成一个函数,具体的任务是一个Python脚本(job.py)

    #coding=utf-8
    
    import time
    import sys
    
    time.sleep(5)
    print("{} finished!".format(sys.argv[1]))
    

    执行结果如下,按照同步顺序一个一个执行

    root@ubuntu:~/Shell# bash test.sh
    job1 finished!
    job2 finished!
    job3 finished!
    所有任务完成!
    

    Shell函数实战

    使用Shell函数封装spark-submit任务,将任务的class,启动参数都作为函数参数传入,实现一个Shell脚本第一个job顺序执行

    #!/bin/bash
    cd /home/PiraRiskScore
    
    start_date=$1
    end_date=$2
    
    echo "执行的开始日期为:${start_date}"
    echo "执行的结束日期为:${end_date}"
    
    if [ $# -ne 2 ];then
      echo "[Usage] 请输入执行的开始时间和结束时间,格式为:yyyy-MM-dd!!!"
      exit $#
    fi
    
    
    spark_job() {
        echo "--------执行:$1"
        sudo -u hdfs spark2-submit \
        --class com.example.PiraRiskScore.main.$1 \
        --master yarn \
        --num-executors $2 \
        --executor-cores $3 \
        --executor-memory 10G \
        --conf spark.yarn.executor.memoryOverhead=12288 \
        --conf spark.dynamicAllocation.enabled=false \
        --conf spark.network.timeout=300 \
        --conf spark.sql.shuffle.partitions=100 \
        PiraRiskScore-1.0-SNAPSHOT.jar \
        ${start_date}
    }
    
    
    while [[  "${start_date}" < "${end_date}" ]]
    do
        echo "------------开始${start_date}的任务"
        spark_job PiraRiskFeature 70 3  && \
        spark_job PiraRiskDetail 25 3  && \
        spark_job PiraRiskModel 25 3  && \
        spark_job PiraRiskScore 25 3  && \
        spark_job PiraRiskScoreIndustry 25 3 && \
        spark_job PiraRiskRank 25 3 && \
        /usr/bin/python push_detail.py $start_date && \
        /usr/bin/python push_score.py $start_date && \
        /usr/bin/python push_score_industry.py $start_date
        if [ $? -ne 0 ];then
            echo "------------任务报错:${start_date}"
            break
        fi
        echo "------------完成${start_date}的任务"
        start_date=$(date -d "$start_date +1day"  +%Y-%m-%d)
    done
    echo "------------存量${start_date}->${end_date}已经完成"
    

    相关文章

      网友评论

        本文标题:Linux Shell:Shell函数使用

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