文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Bash 初学者系列 9:在 bash 中使用函数

2024-12-01 01:18

关注

当你的 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


来源:TIAP内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯