zoukankan      html  css  js  c++  java
  • shell编程系列6--shell中的函数

    shell编程系列6--shell中的函数
    
    
    1.函数介绍
    
    linux shell中的函数和大多数编程语言中的函数一样
    将相似的任务或者代码封装到函数中,供其他地方调用
    
    语法格式
    
    第一种格式
    
    name()
    {
        command1
        command2
        ......
        commondn
    }
    
    第二种格式
    
    function name
    {
        command1
        command2
        ......
        commondn
    }
    
    2.调用函数
    
    直接使用函数名调用,可以将其想象成shell中的一条命令
    
    函数内部可以直接使用参数 $1、$2...$n
    
    调用函数:function_name $1 $2
    
    shell终端中定义函数
    
    [root@es01 shell]# test()
    > {
    >     echo "test function"
    > }
    [root@es01 shell]# 
    [root@es01 shell]# test
    test function
    
    [root@es01 shell]# function greeting
    > {
    >     echo "hello,zhangsan"
    > }
    [root@es01 shell]# greeting 
    hello,zhangsan
    
    
    练习;nginx的守护进程
    
    [root@es01 shell]# cat nginx_daemon.sh 
    #!/bin/bash
    #
    # 获取脚本子进程的pid,如果脚本名称中带nginx,也会当成nginx进程
    this_pid=$$
    
    while true
    do
    ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null
    
    
    if [ $? -eq 0 ];then
        echo "Nginx is running well"
        sleep 5
    else
        systemctl start nginx
        echo "Nginx is down,Start it..."
    fi
    done
    
    
    [root@es01 shell]# nohup sh nginx_daemon.sh &
    [1] 97855
    [root@es01 shell]# nohup: ignoring input and appending output to ‘nohup.out’
    
    [root@es01 shell]# tail -f nohup.out 
    Nginx is running well
    Nginx is running well
    Nginx is running well
    Nginx is running well
    
    4.向函数传递参数
    
    高级语言传参
    
    int example_1(int arg1,int arg2)
    {
        arg1=arg2
        ...
        ...
        return null
    }
    
    高级语言函数调用
    
    int num1=10;
    int num2=20;
    
    调用函数形式一:int num3=example_1(num1,num2);
    调用函数形式二:
            int num4;
            num4=example_1(num1,num2);
    
    shell中传参
    
    function name
    {
        echo "Hello $1"
        echo "Hello $2"
    }
    
    shell中函数调用
    函数调用:name Lily Allen
    
    
    [root@es01 shell]# function greeting
    > {
    > echo "hello zhangsan"
    > }
    [root@es01 shell]# greeting
    hello zhangsan
    
    # 调用参数
    [root@es01 shell]# function greeeting
    > {
    >     echo "hello $1"
    > }
    [root@es01 shell]# greeeting jack
    hello jack
    [root@es01 shell]# greeeting tom
    hello tom
    
    向函数传递参数:
    函数传参和给脚本传参类似,都是使用$1 $2 $3 $4 $5 $6 $7这种方式
    
    例子1:
    需求描述:写一个脚本,该脚本可以实现计算器的功能,可以进行+-*/四种运算。
    例如:sh calculate.sh 30 + 40 | sh calucate.sh 30 - 40
    
    
    [root@es01 shell]# cat calucate.sh 
    #!/bin/bash
    #
    
    function calcu
    {
        case $2 in
            +)
                echo "`expr $1 + $3`"
                ;;
            -)
                echo "`expr $1 - $3`"
                ;;
            *)
                echo "`expr $1 * $3`"
                ;;
            /)
                echo "`expr $1 / $3`"
                ;;
        esac
    }
    
    calcu $1 $2 $3
    
    
    [root@es01 shell]# sh calucate.sh 20 + 30
    50
    [root@es01 shell]# sh calucate.sh 20 - 30
    -10
    
    5.函数的返回值
    
    方法一 return
    方法二 echo
    
    使用return返回值
    使用return返回值,只能返回1-255的整数
    
    函数使用return返回值,通常只是用来供其他地方调用获取状态,因此通常仅返回0或1;0表示成功,1表示失败
    
    # 判断nginx进程是否存在
    [root@es01 shell]# cat nginx.sh 
    #!/bin/bash
    #
    
    this_pid=$$
    
    function is_nginx_running
    {
        ps -ef | grep nginx | grep -v grep | grep -v $this_pid &> /dev/null
        if [ $? -eq 0 ];then
            return 0
        else
            return 1
        fi
    }
    
    is_nginx_running && echo "nginx is running" || echo "nginx is stopped"
    
    [root@es01 shell]# sh nginx.sh 
    nginx is running
    [root@es01 shell]# systemctl stop nginx
    [root@es01 shell]# sh nginx.sh 
    nginx is stopped
    [root@es01 shell]# sh -x nginx.sh 
    + this_pid=101185
    + is_nginx_running
    + ps -ef
    + grep nginx
    + grep -v grep
    + grep -v 101185
    + '[' 1 -eq 0 ']'
    + return 1
    + echo 'nginx is stopped'
    nginx is stopped
    
    
    使用echo返回值
    
    使用echo可以返回任何字符串结果
    
    通常用于返回数据,比如一个字符串值或者列表值
    
    # 获取系统中的用户
    [root@es01 shell]# cat get_sys_user.sh 
    #!/bin/bash
    #
    
    # 获取系统所有的用户名
    function get_users
    {
        users=`cat /etc/passwd | cut -d: -f1`
        echo $users
    }
    
    # 定义一个变量将获取用户列表赋值给这个变量
    user_list=`get_users`
    
    index=1
    for u in $user_list
    do
        echo "the $index user is : $u"
        index=$(($index+1))
    done
    
    
    [root@es01 shell]# sh get_sys_user.sh 
    the 1 user is : root
    the 2 user is : bin
    the 3 user is : daemon
    the 4 user is : adm
    the 5 user is : lp
    the 6 user is : sync
    the 7 user is : shutdown
    the 8 user is : halt
    the 9 user is : mail
    the 10 user is : operator
    the 11 user is : games
    the 12 user is : ftp
    the 13 user is : nobody
    the 14 user is : systemd-network
    the 15 user is : dbus
    the 16 user is : polkitd
    the 17 user is : sshd
    the 18 user is : postfix
    the 19 user is : ajie
    the 20 user is : chrony
    the 21 user is : elasticsearch
    the 22 user is : nginx
    
    6.shell函数中的局部变量和全局变量
    
    不做特殊声明,shell中变量都是全局变量
    
    大型脚本程序函数中慎用全局变量
    
    局部变量:
    
    在函数内部定义局部变量时,使用local关键字
    
    函数内和函数外若同时存在变量,函数内部变量会覆盖外部变量
    
    # 
    [root@es01 shell]# cat var.sh 
    #!/bin/bash
    #
    
    var1="Hello world"
    
    function test
    {
        var2=87
    }
    
    echo $var1
    echo $var2
    
    # 因为函数test没有被调用,所以变量 $var2 没有生效,为空
    [root@es01 shell]# sh var.sh 
    Hello world
    
    [root@es01 shell]#
    
    # 调用test函数后,$var2就变成了全局变量
    [root@es01 shell]# cat var.sh 
    #!/bin/bash
    #
    
    var1="Hello world"
    
    function test
    {
        var2=87
    }
    
    echo $var1
    echo $var2
    
    test    # 调用test函数后,$var2就变成了全局变量
    
    echo $var1
    echo $var2
    
    [root@es01 shell]# sh var.sh 
    Hello world
    
    Hello world
    87
    
    # 在函数中也可以调用全局变量
    [root@es01 shell]# cat var.sh 
    #!/bin/bash
    #
    
    var1="Hello world"
    
    function test
    {
        var2=87
    }
    
    echo $var1
    echo $var2
    
    test
    
    echo $var1
    echo $var2
    
    function test1
    {
        echo $var2
    }
    
    test1
    [root@es01 shell]# sh var.sh 
    Hello world
    
    Hello world
    87
    87
    
    # 如果函数中声明了局部变量,当函数执行完成后局部变量就会被销毁
    [root@es01 shell]# cat var.sh 
    #!/bin/bash
    #
    
    var1="Hello world"
    
    function test
    {
        local var2=87    # 局部变量,只在函数内部生效,生命周期只在函数内部
    }
    
    test
    
    echo $var1
    echo $var2
    
    [root@es01 shell]# sh var.sh 
    Hello world
    
    [root@es01 shell]# 
    
    7.函数库
    
    为什么需要定义函数库?
    
    经常使用的重复代码可以封装成函数文件,功能函数,程序工具
    
    函数库文件一般不直接执行,而是由其他脚本调用
    
    函数库示例:
    
        定义一个函数库,该函数库实现以下几个函数:
        1.加法函数add
            add 12 89
        2.减法函数reduce
            reduce 90 30
        3.乘法函数multiple
            multiple 12 10
        4.除法函数divide
            divide 9 3
        5.打印系统运行情况的函数sys_load,该函数可以显示内存运行情况,磁盘使用情况
    
    
        # 定义库函数
        [root@es01 shell]# cat lib/base_function 
        function add
        {
            echo "`expr $1 + $2`"
        }
    
        function reduce
        {
            echo "`expr $1 - $2`"
        }
    
        function multiple
        {
            echo "`expr $1 * $2`"
        }
    
        function divide
        {
            echo "`expr $1 / $2`"
        }
    
        function sys_load
        {
            echo "Memory info"
            echo 
            free -m
            echo
            echo "Disk Usage"
            echo
            df -h
            echo
        }
    
        # 测试库函数
        [root@es01 shell]# . lib/base_function 
        [root@es01 shell]# sys_load
        Memory info
    
                  total        used        free      shared  buff/cache   available
        Mem:           3773         123        3300          11         348        3389
        Swap:          2047           0        2047
    
        Disk Usage
    
        Filesystem               Size  Used Avail Use% Mounted on
        /dev/mapper/centos-root   49G  3.3G   46G   7% /
        devtmpfs                 1.9G     0  1.9G   0% /dev
        tmpfs                    1.9G     0  1.9G   0% /dev/shm
        tmpfs                    1.9G   12M  1.9G   1% /run
        tmpfs                    1.9G     0  1.9G   0% /sys/fs/cgroup
        /dev/sda1                297M  125M  172M  43% /boot
        /dev/mapper/centos-data   49G   33M   49G   1% /data
        tmpfs                    378M     0  378M   0% /run/user/0
    
        # 调用库函数
        [root@es01 shell]# cat calculate.sh 
        #!/bin/bash
        #
    
        # 引入库函数,写绝对路径避免出错
        . /data/shell/lib/base_function
    
        add 12 23
    
        reduce 90 30
    
        multiple 12 12
    
        divide 12 2
    
    
    经验之谈:
    库文件名的后缀是任意的,但一般使用.lib
    
    库文件通常没有可执行权限
    
    库文件无需和脚本放在同级目录,只需要在脚本中引用时指定
    
    第一行一般使用#!/bin/echo,输出警告信息,避免用户执行
  • 相关阅读:
    复制文字时自动加版权
    Linux安装Docker
    ThreadLocal 理解
    Spring多数据源动态切换
    [LOJ#500]「LibreOJ β Round」ZQC的拼图
    [JLOI2015]装备购买
    「雅礼集训 2017 Day4」洗衣服
    [BJWC2011]元素
    [51nod1577]异或凑数
    [ARC101B]Median of Medians
  • 原文地址:https://www.cnblogs.com/reblue520/p/10935407.html
Copyright © 2011-2022 走看看