Shell 编程(二):Shell 函数的高级用法

2023-02-17 17:08:53 浏览数 (1)

函数定义和使用

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

语法格式

方法

格式内容

方法一

name() {  command1  command2 … conmandn }

方法二

function name{ command1 command2 … commandn}

代码语言:javascript复制
#!/bin/bash

# 方法一
test()
{
    echo "test function";
}

# 方法二
function greeting
{
    echo "hello,Zhangsan";
}

test
greeting

输出

代码语言:javascript复制
test function
hello,Zhangsan

例子

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

代码语言:javascript复制
# nginx_daemon.sh
#!/bin/bash
# 获取当前脚本运行的子id,防止 ps 命令误认
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

# bash
> nohup sh nginx_ daemon. sh &
[1] 76378
> tail -f nohup.out
Nginx is running well
Nginx is running well
Nginx is running well
Nginx is running well
  • 直接使用函数名调用,可以将其想象成 Shell 中的一条命令
  • 函数内部可以直接使用参数1、2…、

函数传参

调用格式

代码语言:javascript复制
# name 为函数
name xxx xxx

> function greeting
> {
>    echo "hello,$1" 
> }
> greeting chendasheng
hello chendasheng

例子

写一个脚本,该脚本可以实现计算器的功能,可以进行 、-、*、/ 四种计算。

代码语言:javascript复制
# example3.sh
#!/bin/bash
function calculate
{
    case "$2" in
         )
            echo "`expr $1   $3`";
            ;;
        -)
            echo "`expr $1 - $3`";
            ;;
        *)
            echo "`expr $1 * $3`";
            ;;
        /)
            echo "`expr $1 / $3`";
            ;;
    esac
}

calculate $1 $2 $3

# bash
> sh example3.sh 5   6
11
> sh example3.sh 100 / 6
16

函数返回值

方法

函数

方法一

return

方法二

echo

使用 return 返回值

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

使用echo返回值

  • 使用echo可以返回任何字符串结果
  • 通常用于返回数据,比如一个字符串值或者列表值

例子

Nginx 函数引用返回值

代码语言:javascript复制
#!/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"

局部变量和全局变量

全局变量

  • 不做特殊声明, Shell中变量都是全局变量

大型脚本程序中函数中慎用全局变量

局部变量

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

例子

代码语言:javascript复制
# example5.sh
#!/bin/bash
var1="Hello world"

function test
{
    var2=87
    local var3=86
    echo $var3
}
echo $var1
echo $var2
echo $var3

test

echo $var1
echo $var2
echo $var3

function test1
{
    echo $var2
    echo $var3
}

test1

输出

代码语言:javascript复制
> sh example5.sh
Hello world


86
Hello world
87

87

函数库

为什么要定义函数库,

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

例子

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

  1. 加法函数 add
  2. 减法函数 reduce
  3. 乘法函数 multiple
  4. 除法函数 divide
  5. 打印系统运行情况的函数sys_load,该函数可以显示内存运行情况,磁盘使用情况
代码语言:javascript复制
# base_function.lib
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 Info"
    echo
    df -h
    echo 
}


# example6.sh
#!/bin/bash
. /Users/chendashengpc/code/shell/advanced-usage-of-function/base_function.lib

add 1 3
reduce 3 4
multiple 7 8
divide 9 10 
sys_load

输出

代码语言:javascript复制
4
-1
56
0
Memory Info

              total        used        free      shared  buff/cache   available
Mem:           7678        2371         461          84        4844        4924
Swap:             0           0           0

Disk Info

Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        3.8G     0  3.8G   0% /dev
tmpfs           3.8G   16K  3.8G   1% /dev/shm
tmpfs           3.8G  572K  3.8G   1% /run
tmpfs           3.8G     0  3.8G   0% /sys/fs/cgroup
/dev/vda1        79G   19G   57G  26% /
tmpfs           768M     0  768M   0% /run/user/1001
tmpfs           768M     0  768M   0% /run/user/0

经验之谈

  • 库文件名的后缀是任意的,但一般使用 .lib
  • 库文件通常没有可执行选项
  • 库文件无需和脚本在同级目录,只需在脚本中引用时指定
  • 第一行一般使用 #!/bin/echo 输出警告信息,避免用户执行

0 人点赞