当你的 bash 脚本中代码非常多的时候,会看起来很混乱,其中有部分代码有可能是重复的。这个时候,可以使用函数来避免重复的代码。
今天我们将介绍在 bash 中如何创建函数,以及函数中的返回值、传递参数等内容。
在 bash 中创建函数
创建 bash 函数有两种不同的语法。最常用的方法如下:
function_name () { commands}第二种方法不太常用,如下所示:
function function_name { commands}在使用函数时,需要注意以下几点:
除非被调用,否则函数永远不会被执行;函数必须先定义,然后才能被调用。作为演示,我们创建一个 fun.sh 脚本,如下代码:
#!/bin/bashhello () {echo hello world}hellohellohello上述脚本中,我们定义了一个名为 hello 的函数,它将在终端上打印 hello world。后面我们调用了三次 hello 函数,因此,运行脚本后,你会在屏幕上看到 hello world 打印了三次:
$ ./fun.shhello worldhello worldhello world函数的返回值
在很多编程语言中,函数在调用时都会返回一个值,然而,在 bash 函数中没有返回值。
当函数执行完成时,会返回一个 $? 变量作为退出状态,0 表示成功执行,其他非零正整数(1 - 255)表示执行失败。
我们来写一个例子,命名为 error.sh,在其中写一个 return 语句,如下代码所示:
#! /bin/basherror () {blablareturn 0}errorecho the return status of the error function is: $?执行结果如下:
$ ./error.sh./error.sh: line 4: blabla: command not foundthe return status of the error function is: 0因为有 return 0 这一行,所以即使函数中有 blabla 这一行的报错,error 函数还是返回了一个执行成功的状态码 0。
return 语句执行后,函数会被立即终止。
向 bash 函数传递参数
我们可以向函数传递参数,就像向 bash 脚本传递参数一样。
作为演示,我们创建一个名为 iseven.sh 的脚本,如下所示:
#!/bin/bashiseven () { if [ $(($1 % 2)) -eq 0 ]; then echo $1 is even. else echo $1 is odd. fi}iseven 3iseven 4iseven 20iseven 111iseven() 函数判断数字是偶数还是奇数。在调用的时候,将参数放在函数名后面,函数执行的时候会读取 $1 来获取传递的参数。我们来执行一下:
$ ./iseven.sh3 is odd.4 is even.20 is even.111 is odd.这里需要注意,bash 函数中的参数,和 bash 脚本的参数需要区分开来,看如下 funarg.sh 脚本:
#!/bin/bashfun () {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 stuffcool 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/bashv1='a'v2='b'myfun() { local v1='c' v2='d' echo inside myfun(): v1: $v1, v2: $v2}echo before calling myfun(): v1: $v1, v2: $v2myfunecho after calling myfun(): v1: $v1, v2: $v2我们首先定义了两个全局变量 **v1 和 v2 ,然后在 函数 myfun() 中,使用 local 关键字 定义了一个局部变量 ** v1 ,并修改了全局变量 v2 。在不同的函数中,局部变量可以使用相同的变量名。
执行一下,结果如下:
$ ./scope.shbefore calling myfun(): v1: a, v2: binside myfun(): v1: c, v2: dafter calling myfun(): v1: a, v2: d由此,我们可以看到:
如果局部变量的变量名与全局变量的变量名相同,那么局部变量优先级会更高;在函数中可以更改全局变量的值。递归函数
递归函数是一个调用自身的函数。阶乘计算是递归函数的经典例子,看下面的脚本 factorial.sh:
#!/bin/bashfactorial () { if [ $1 -le 1 ]; then echo 1 else last=$(factorial $(( $1 -1))) echo $(( $1 * last )) fi}echo -n 4! is: factorial 4echo -n 5! is: factorial 5echo -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.sh4! is: 245! is: 1206! is: 720
传骁龙875已用台积电5nm芯片生产 或将明年亮相
电容屏的使用缺陷是什么,它有什么缺点
薄膜电阻和厚膜电阻的区别是什么?哪个好?
智能物联网解决方案:蓝牙IOT主控模块打造高效监测和超低功耗
NASA打造能在金星表面执行任务超强无人机
在bash中如何创建函数
NI为美海军提供通信测试设备
中兴通讯发布政企业务“双百千”商业合作计划
基于EAIDK310的视觉导航自动驾驶小车
瑞萨电子和Green Hills软件公司合作开发网联驾驶舱演示车
份额增66%!海尔智家厨电“卖场景”收获用户
家用电器电动机及变压器的自复电路保护
智能手机是过去十年这个世界高速增长最大的驱动力
物联网支持企业转型 深度融合带来巨大回报
世界首艘锂电池潜艇下水,电动车锂电池市场还有多远
恩智浦与长安汽车宣布建立长期战略合作伙伴关系
ZX430-S3RI1串口屏产品概要及核心优势
3D打印机的速度怎么设置
物联网应用的开发怎样去规划
深度剖析振荡器电路中晶体的高稳定性