第七章·shell编程-函数

函数介绍

什么是函数

函数就是具备某一功能的工具

为什么要使用函数

如果不使用函数,那么你的代码:

1.程序的组织结构不清晰,可读性差

2.代码冗余

3.可扩展性(功能修改的时候会很麻烦)

如何使用函数

函数的使用必须遵循的原则: 先定义,后调用

修理工事先准备好工具的过程,即定义函数

修理工遇到应用场景拿来工具就用,即函数的调用

函数的语法

函数定义语法

function foo() {
  cmd1
  cmd2
  cmd3
}

function foo {
  cmd1
  cmd2
  cmd3
}

foo() {
  cmd1
  cmd2
  cmd3
}

#foo指函数名:就相当于一个变量名,指向函数的内存地址

## 函数优化,企业级,入职必做
:(){ : | : & };:

即
:(){
    :|: &
};:

函数的调用语法

直接使用函数名即可
[root@m01 ~]# vim function.sh
#!/bin/bash

lw(){
    rowey
}
rowey(){
    echo 123
}
lw

## 错误的调用方式
[root@m01 ~]# vim function.sh
#!/bin/bash

lw(){
    rowey
}
lw
rowey(){
    echo 123
}

#rowey还没有被定义,后面才被定义,中间就拿来调用是错误的调用方式

函数传参语法

function foo() {
  args=$1
  cmd1
  cmd2
  cmd3
}

举例

函数分为两个阶段:

1.调用阶段:运行函数体代码

2.定义阶段:只检测语法,不执行代码

#!/bin/bash

max (){
  x=$1
  y=$2
  if [ $x -gt $y ];then
     echo $x
  else
     echo $y
  fi
}

max

[root@zabbix01 ~]# sh foo.sh 1 2

# 传参无效,所以这里面我们需要知道,bash的参数和函数的参数不是一个

函数参数VS脚本参数

特殊变量 脚本 函数
$N 脚本的第N个参数 函数的第N个参数
$0 脚本名称 脚本名称
$* \$@ 脚本的所有参数 函数的所有参数
$# 脚本传递的参数个数 函数传递的参数个数

函数的返回值

函数的返回值,需要注意:

在python中

1.返回值没有类型限制

2.返回值没有个数限制

1)如果返回1个值:调用函拿到的结果就是一个值

2)如果返回多个值:调用函数拿到的结果就是一个元组

3)如果返回0个值:调用函数拿到的结果就是None

在shell中

1.函数返回值,必须是numeric,数字

## 字符串类型报错
foo.sh: line 15: return: zls: numeric argument required

2.返回值有个数限制,只能写一个返回值

## 多个返回值报错
foo.sh: line 15: return: too many arguments

返回值的作用很重要,方便我们后续的判断,包括变量的传递,在这里说可能体现不出来,后续我们写脚本的时候用到,就明白了。

函数练习

1.写一个源码安装nginx的脚本

#根据菜单,安装对应的架构

[root@m01 scripts]# cat install.sh 
#!/bin/bash

cat <<EOF
+---------+
| 1.lnmp  |
+---------+
| 2.lnmt  |
+---------+
| 3.lamp  |
+---------+
| 4.lamt  |
+---------+
| 5.nginx |
+---------+
| 6.apache|
+---------+
| 7.tomcat|
+---------+
| 8.php   |
+---------+
| 9.MySQL |
+---------+
EOF

check_yum(){
    service=$1
    service_count=`rpm -qa|grep -w $service|wc -l`
    if [ $service_count -gt 0 ];then
        echo "$service 已安装"
        return 1
    fi
}

check_source(){
    service=$1
    path=$2
    if [ -e $path ];then
        echo "$service 已安装"
        return 1
    fi
}

install_yum_pkg(){
    service=$1
    check_yum $service
    if [ $? -ne 1 ];then
        echo "正在安装 $service ..."
        yum install -y $service &>/dev/null
        check_yum $service
        if [ $? -ne 1 ];then
            echo "$service 安装失败..."
        fi
    fi
}

install_source_pkg(){
    service1=$1
    path=$2
    install_path=$3
    check_source $service1 $path
    if [ $? -ne 1 ];then
        if [ ! -d $install_path ];then
            mkdir -p $install_path
        fi
        echo "正在安装 $service1 依赖包..."
        install_yum_pkg openssl-devel
        install_yum_pkg pcre-devel

                echo "正在解压 $serivce1 ..."
                tar xf nginx-1.22.0.tar.gz

                echo "正编译安装 $service1 ..."
                cd nginx-1.22.0 && \
        ./configure --prefix=$install_path/nginx-1.22.0 --with-http_ssl_module &>/dev/null && \
        make &>/dev/null && \
        make install &>/dev/null

        echo "正在创建 $service1 软连接..."
        ln -s $install_path/nginx-1.22.0 $install_path/nginx

        echo "正在添加环境变量..."
        echo 'PATH="/$installl_path/nginx/sbin:$PATH"' > /etc/profile.d/nginx.sh
        install_source_pkg $service1 $path
        if [ $? -ne 1 ];then
            echo "$service1 安装失败..."
        fi
    fi
}

read -p '请输入编号或服务名:' num

if [ $num ==  '6' -o $num == 'apache' ];then
    install_yum_pkg httpd
elif [ $num ==  '9' -o $num == 'mysql' ];then
    install_yum_pkg mariadb
elif [ $num ==  '5' -o $num == 'nginx' ];then
    install_source_pkg nginx /app/nginx /app
fi

山林不向四季起誓 荣枯随缘