前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Shell 编程(二):Shell 函数的高级用法

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

作者头像
陈大剩博客
发布2023-02-17 17:08:53
5630
发布2023-02-17 17:08:53
举报
文章被收录于专栏:陈大剩博客专栏

函数定义和使用

  • 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 输出警告信息,避免用户执行
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-01-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 函数定义和使用
    • 语法格式
      • 例子
      • 函数传参
        • 例子
        • 函数返回值
          • 使用 return 返回值
            • 使用echo返回值
              • 例子
              • 局部变量和全局变量
                • 全局变量
                  • 局部变量
                    • 例子
                    • 函数库
                      • 为什么要定义函数库,
                        • 例子
                          • 经验之谈
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档