【Shell脚本编程(二)】函数的高级用法

1. 函数定义和使用

1.1. 函数介绍

  • Linux Shell 中的函数和大多数编程语言中的函数一样;
  • 将相似的任务或代码封装到函数中,供其他地方调用;

1.2. 语法格式

第一种格式:

name()
{
    command1
    command2
    ......
    commandn
}

第二种格式:

function name
{
    command1
    command2
    ......
    commandn
}

1.3. 如何调用函数

  • 直接使用函数名调用,可以将其想象成Shell中的一条命令;
  • 函数内部可以直接使用参数1、¥2...1、¥2...1¥2...n
  • 调用函数:function_name $1 $2
test()
{
    echo "test function"
}

test  #结果为test function


function greeting
{
    echo "hello,zhangsan"
}

greeting  #结果为hello,zhangsan

需求描述:写一个监控nginx的脚本;如果Nginx服务宕掉,则该脚本可以检测到并将进程启动;如果正常运行,则不做任何处理。

vim nginx_daemon.sh

############脚本文件内容##############

#!/bin/bash
#

ps -ef | grep nginx | grep -v grep

echo $?
############脚本文件内容##############

#将nginx停掉后执行
sh nginx_daemon.sh  #结果为0,是因为虽然过滤掉grep nginx,但是脚本文件名称仍然存在nginx(nginx_daemon.sh)

#修改脚本文件名称
mv nginx_daemon.sh daemon.sh
sh daemon.sh  #结果为1

#或者在脚本中这样实现
#!/bin/bash
#

this_pid=$$

ps -ef | grep nginx | grep -v grep | grep -v $this_pid

echo $?

#完整实现脚本
#!/bin/bash
#

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 3
else
    systemctl start nginx
    echo "Nginx is down,Start it..."
fi
done
##############脚本文件内容################

#如果不希望终端打印提示信息则执行
nohup sh nginx_daemon.sh &

#查看打印的日志信息
tail -f nohup.out

2. 向函数传递参数

2.1. 高级语言传参

int example_1(int arg1, int arg2)
{
    arg1=arg2
    ......
    ......
    return null
}

2.2. 高级语言函数调用

int num1=10;
int num2=20;

#调用函数形式一:
int num3=example_1(num1,num2);

#调用函数形式二:
int num4;
num4=example_1(num1,num2);

2.3. Shell中传参

function name
{
    echo "Hello $1"
    echo "Hello $2"
}

2.4. Shell中函数调用

函数调用:name Lily Allen

funciton greeting
{
    echo "Hello $1"
}

greeting zhangsan  #结果为Hello Zhangsan
greeting Lisi  #结果为Hello Lisi

例子1:

需求描述:写一个脚本,该脚本可以实现计算器的功能,可以进行±*/四种计算。例如:sh calculate.sh 30 + 40 | sh calculate.sh 30 - 40 | sh calculate.sh 等。

#计算器脚本
vim calculate.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

3. 函数返回值

3.1. 返回值的方式

方法代码
方法一return
方法二echo

3.2. 使用return返回值

  • 使用return返回值,只能返回1-255的整数
  • 函数使用return返回值,通常只是用来供其他地方调用获取状态,因此通常仅返回0或1;0表示成功,1表示失败;

3.3. 使用echo返回值

  • 使用echo可以返回任何字符串结果;
  • 通常用于返回数据,比如一个字符串值或者列表值;
vim 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
    else
        return 1
    fi
}

is_nginx_running && echo "Nginx is running" || echo "Nginx is stoped"
vim 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

4. 局部变量和全局变量

4.1. 全局变量

  • 不做特殊声明,Shell中变量都是全局变量;
  • Tips:大型脚本程序中函数中慎用全局变量;

4.2. 局部变量

  • 定义变量时,使用local关键字;
  • 函数内和外若存在同名变量,则函数内部变量覆盖外部变量;
vim var.sh

#!/bin/bash
#
var1="Hello world"

function test
{
    local var2=87
}

test
echo $var1
echo $var2

5. 函数库

5.1. 为什么要定义函数库

  • 经常使用的重复代码封装成函数文件;
  • 一般不直接执行,而是由其他脚本调用;

函数库:

定义一个函数库,该函数库实现以下几个函数:

  1. 加法函数add;
  2. 减法函数reduce;
  3. 乘法函数multiple;
  4. 除法函数divide;
  5. 打印系统运行情况的函数sys_load,该函数可以显示内存运行情况,磁盘使用情况;
vim 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
}


###############################################
vim calculate.sh

#!/bin/bash
#

. /root/lesson/3.5/lib/base_function  #引入函数库(函数库文件所在的绝对路径)

add 12 23

reduce 90 30
 
multiple 12 12

divide 12 2

sys_load

5.2. 经验之谈

  • 库文件名的后缀是任意的,但一般使用.lib;
  • 库文件通常没有可执行选项;
  • 库文件无需和脚本在同级目录,只需在脚本中引用时指定;
  • 第一行一般使用#!/bin/echo,输出警告信息,避免用户执行;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值