0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在bash中如何创建函数

CHANBAEK 来源:TIAP 作者:TIAP 2022-12-14 17:31 次阅读

当你的 bash 脚本中代码非常多的时候,会看起来很混乱,其中有部分代码有可能是重复的。这个时候,可以使用函数来避免重复的代码。

今天我们将介绍在 bash 中如何创建函数,以及函数中的返回值、传递参数等内容。

在 bash 中创建函数

创建 bash 函数有两种不同的语法。最常用的方法如下:

function_name () {
    commands
}

第二种方法不太常用,如下所示:

function function_name {
    commands
}

在使用函数时,需要注意以下几点:

  • 除非被调用,否则函数永远不会被执行;
  • 函数必须先定义,然后才能被调用。

作为演示,我们创建一个 fun.sh 脚本,如下代码:

#!/bin/bash


hello () {
echo "Hello World"
}


hello
hello
hello

上述脚本中,我们定义了一个名为 hello 的函数,它将在终端上打印 Hello World。后面我们调用了三次 hello 函数,因此,运行脚本后,你会在屏幕上看到 Hello World 打印了三次:

$ ./fun.sh
Hello World
Hello World
Hello World

函数的返回值

在很多编程语言中,函数在调用时都会返回一个值,然而,在 bash 函数中没有返回值。

当函数执行完成时,会返回一个 $? 变量作为退出状态,0 表示成功执行,其他非零正整数(1 - 255)表示执行失败。

我们来写一个例子,命名为 error.sh,在其中写一个 return 语句,如下代码所示:

#! /bin/bash


error () {
blabla
return 0
}


error
echo "The return status of the error function is: $?"

执行结果如下:

$ ./error.sh
./error.sh: line 4: blabla: command not found
The return status of the error function is: 0

因为有 return 0 这一行,所以即使函数中有 blabla 这一行的报错,error 函数还是返回了一个执行成功的状态码 0。

return 语句执行后,函数会被立即终止。

向 bash 函数传递参数

我们可以向函数传递参数,就像向 bash 脚本传递参数一样。

作为演示,我们创建一个名为 iseven.sh 的脚本,如下所示:

#!/bin/bash


iseven () {
    if [ $(($1 % 2)) -eq 0 ]; then
        echo "$1 is even."
    else
        echo "$1 is odd."
    fi
}


iseven 3
iseven 4
iseven 20
iseven 111

iseven() 函数判断数字是偶数还是奇数。在调用的时候,将参数放在函数名后面,函数执行的时候会读取 $1 来获取传递的参数。我们来执行一下:

$ ./iseven.sh
3 is odd.
4 is even.
20 is even.
111 is odd.

这里需要注意,bash 函数中的参数,和 bash 脚本的参数需要区分开来,看如下 funarg.sh 脚本:

#!/bin/bash


fun () {
echo "$1 is the first argument to fun()"
echo "$2 is the second argument to fun()"
}


echo "$1 is the first argument to the script."
echo "$2 is the second argument to the script."


fun Yes 7

执行结果如下:

$ ./funarg.sh Cool Stuff
Cool is the first argument to the script.
Stuff is the second argument to the script.
Yes is the first argument to fun()7 is the second argument to fun()

可以看到,同样是使用 $1 和 $2 来引用脚本参数和函数参数,当实际调用时,取值是不同的。

bash 函数中的全局变量和局部变量

与大多数编程语言累死,bash 变量具有全局变量和局部变量之分。其中全局变量可以在任何位置方位到,而局部变量只能在其定义的函数中访问。

作为演示,看如下 scope.sh 脚本:

#!/bin/bash


v1='A'
v2='B'


myfun() {
    local v1='C'
    v2='D'
    echo "Inside myfun(): v1: $v1, v2: $v2"
}


echo "Before calling myfun(): v1: $v1, v2: $v2"
myfun
echo "After calling myfun(): v1: $v1, v2: $v2"

我们首先定义了两个全局变量 **v1 v2 ,然后在 函数 myfun() 中,使用 local 关键字 定义了一个局部变量 ** v1 ,并修改了全局变量 v2 。在不同的函数中,局部变量可以使用相同的变量名。

执行一下,结果如下:

$ ./scope.sh
Before calling myfun(): v1: A, v2: B
Inside myfun(): v1: C, v2: D
After calling myfun(): v1: A, v2: D

由此,我们可以看到:

  • 如果局部变量的变量名与全局变量的变量名相同,那么局部变量优先级会更高;
  • 在函数中可以更改全局变量的值。

递归函数

递归函数是一个调用自身的函数。阶乘计算是递归函数的经典例子,看下面的脚本 factorial.sh:

#!/bin/bash


factorial () {
    if [ $1 -le 1 ]; then
        echo 1
    else
        last=$(factorial $(( $1 -1)))
        echo $(( $1 * last ))
    fi
}


echo -n "4! is: "
factorial 4
echo -n "5! is: "
factorial 5
echo -n "6! is: "
factorial 6

任何递归函数都要从一个基本条件开始,这个基本条件必须可以结束递归函数调用链。在 factorial() 函数中,基本条件为:

if [ $1 -le 1 ]; then
    echo 1

然后导出阶乘函数的递归情况。要计算 n 的阶乘,其中 n 是大于 1 的正数,可以将 n 乘以 n-1 的阶乘:

factorial(n) = n * factorial(n-1)

使用上面那个公式来编写递归函数的算法

last=$(factorial $(( $1 -1)))
    echo $(( $1 * last ))

然后运行一下,检查运行结果:

$ ./factorial.sh
4! is: 24
5! is: 120
6! is: 720
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4331

    浏览量

    62622
  • 脚本
    +关注

    关注

    1

    文章

    389

    浏览量

    14866
  • Bash
    +关注

    关注

    0

    文章

    57

    浏览量

    10184
收藏 人收藏

    评论

    相关推荐

    如何在bash脚本创建第一个数组

    在前面的文章,我们介绍了如何在 bash 中使用有限数量的变量,比如要保存一个或两个文件名或用户名。
    发表于 12-02 16:53 854次阅读
    如何在<b class='flag-5'>bash</b>脚本<b class='flag-5'>中</b><b class='flag-5'>创建</b>第一个数组

    labview创建文件函数时出现 memory is full 的问题

    `labview创建文件函数时出现 memory is full 的问题,这个问题是不是由于没有加入关闭文件函数引起的呢`
    发表于 12-25 14:12

    如何更新Vivado 2014.2bash shell版本?

    如何更新Vivado 2014.2bash shell版本?谢谢!
    发表于 03-20 07:47

    为什么UCOSIII外部中断服务函数不能开启已经创建的软件定时器?

    一个外部中断服务函数,开启一个已经创建的软件定时器,会开启不成功返回的错误码:OS_ERR_TMR_ISR错误码说明:if the call was made from an IS
    发表于 06-02 14:13

    C语言入门教程-创建一个函数

    创建一个函数库 上述程序的rand和bubble_sort函数很实用,很可能在您写其他程序时也能派上用场。为了能更方便地重复使用,您可以为它们
    发表于 07-29 11:18 3132次阅读

    10个方便的Bash别名

    要使用你创建Bash 别名,你需要将其添加到 .bash_profile ,该文件位于你的家目录。请注意,此文件是隐藏的,并只能从命
    的头像 发表于 10-16 15:00 2735次阅读

    怎样MATLAB创建函数

    。如果这样做不能解决问题,请在“脚本窗口”重新打开函数,并确保没有错误。代码正确输出后,您将成功创建您的第一个MATLAB函数
    的头像 发表于 11-04 11:07 2.1w次阅读
    怎样<b class='flag-5'>在</b>MATLAB<b class='flag-5'>中</b><b class='flag-5'>创建</b><b class='flag-5'>函数</b>

    fork函数的作用_fork函数创建进程

     Linuxfork函数是非常重要的函数,它的作用是从已经存在的进程创建一个子进程,而原进
    发表于 12-01 13:41 7910次阅读
    fork<b class='flag-5'>函数</b>的作用_fork<b class='flag-5'>函数</b><b class='flag-5'>创建</b>进程

    Bash 中比较 $() 与 ${}

    像 Linux 这样的基于 GNU 的操作系统依赖于一个名为 Bash 的命令语言解释器或 Shell 来完成它们的大部分计算任务和目标。
    的头像 发表于 09-09 09:24 676次阅读

    如何在bash shell脚本接受参数

    终端命令通常包含一些参数,使用的时候可以提供不同的参数来确定命令的执行方式。POSIX规范包含了用于命令行接口的选项。这也是与最早的UNIX应用程序建立的一个由来已久的约定,所以当你b
    的头像 发表于 12-09 17:34 2714次阅读

    Bash脚本特殊变量$0是什么?

    Bash 脚本,`$0` 是一个特殊变量,它代表当前脚本的路径和名称。这个变量用于表示脚本自身,它是 Bash 环境的一个重要组成部
    的头像 发表于 05-12 14:41 1846次阅读

    shell脚本基础函数

    bash定义函数 function和函数名字可以任意省略一个 需要注意的是,函数必须在被调用
    的头像 发表于 05-22 09:20 481次阅读
    shell脚本基础<b class='flag-5'>函数</b>

    linux操作系统的进程创建和销毁函数解析

    第一次遇见创建进程是Linux启动流程,reset_init函数调用kernel_thread函数
    发表于 06-26 09:12 730次阅读
    linux操作系统<b class='flag-5'>中</b>的进程<b class='flag-5'>创建</b>和销毁<b class='flag-5'>函数</b>解析

    bash如何进行各种文件重定向呢?

    本文会用以下测试程序,来演示bash,如何进行各种文件重定向
    的头像 发表于 08-25 09:31 1226次阅读
    <b class='flag-5'>在</b><b class='flag-5'>bash</b><b class='flag-5'>中</b>如何进行各种文件重定向呢?

    BASH shell脚本篇—函数

    函数是代码重用的最重要方式。Bash函数可以定义为一组命令,bash脚本多次调用。
    的头像 发表于 10-20 16:31 1107次阅读