在Bash中使用函数

时间:2020-03-05 15:31:36  来源:igfitidea点击:

当你的bash脚本变得更大,更大时,事情会变得非常凌乱!

我们可以在Bash脚本的不同部分中再次发现自己再次重写相同的代码。

幸运的是,我们可以通过使用Bash中的函数来避免重写代码,这将使脚本更加组织和可读。

在本教程中,我们将学习在Bash Shell脚本中创建函数,返回函数值和传递函数参数。

此外,我们将学习变量范围工作以及如何定义递归函数的变量。

在BASH中创建函数

声明Bash函数有两种不同的语法。
以下语法是创建Bash函数的最常用方法:

function_name () {
commands
}

创建Bash函数的第二个常用常用于保留的工作函数后跟函数名称如下:

function function_name {
commands
}

现在,在使用功能时,我们应该清楚有几件事:

  • 除非我们调用/调用函数,否则函数永远不会运行/执行。
  • 函数定义必须先于对函数的任何调用。

如果我们希望运行函数,我们只需调用它!通过简单地引用函数名称来完成函数调用。

看看以下Fun.sh Bash脚本:

#!/bin/bash
hello () {
echo "Hello World"
}
hello
hello
hello

我定义了一个名叫Hello的函数,只需将"Hello World"的线路"的"Hello World"旋转到终端。
请注意,我做了三个Hello函数调用,因此如果我们运行脚本,我们将看到屏幕上打印三次的"Hello World"行:

Hyman@theitroad:~$./fun.sh
Hello World
Hello World
Hello World

返回BASH中的函数值

在许多编程语言中,函数在调用时返回值;但是,由于BASH函数不返回值并非如此。

当Bash函数完成执行时,它会返回以$捕获的最后一个命令的退出状态?
多变的。
归零表示成功执行或者非零正整数(1-255)表示故障。

我们可以使用返回语句来更改函数的退出状态。
例如,查看以下错误脚本:

#! /bin/bash
error () {
blabla
return 0
}
error
echo "The return status of the error function is: $?"

如果我们运行错误.sh bash脚本,则可能会对输出感到惊讶:

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

如果没有返回0语句,则错误函数将永远不会返回非零退出状态,因为Blabla在找不到错误的命令中导出。

因此,尽管虽然Bash函数不返回值,但我通过更改函数退出状态来完成解决方法。

我们还应该意识到返回语句立即终止函数。

将参数传递给Bash函数

我们可以将参数传递给函数,就像我们可以将参数传递给Bash脚本。
我们只需在执行函数调用时包含参数。

要演示,让我们来看看以下是Iseven.sh Bash脚本:

#!/bin/bash
iseven () {
if [ $(( % 2)) -eq 0 ]; then
echo " is even."
else
echo " is odd."
fi
}
iseven 3
iseven 4
iseven 20
iseven 111

ISVEN()函数测试数字是偶数还是奇数。
我对Iseven()做了四个函数调用。
对于每个函数调用,我提供了一个数字,该数字是iseven()函数的第一个增强,并且在函数定义中的$1变量引用。

让我们运行iSeven.sh Bash脚本以确保它有效:

Hyman@theitroad:~$./iseven.sh
3 is odd.
4 is even.
20 is even.
111 is odd.

我们也应该很清楚bash函数参数和bash脚本参数是两个不同的东西。

要对比差异,请查看以下Funarg.sh Bash脚本:

#!/bin/bash
fun () {
echo " is the first argument to fun()"
echo " is the second argument to fun()"
}
echo " is the first argument to the script."
echo " is the second argument to the script."
fun Yes 7

使用几个参数运行脚本并观察结果:

Hyman@theitroad:~$./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变量可以具有全局或者本地范围。

无论范围如何,我们都可以访问Bash脚本中的任何位置的全局变量。
相反,只能从其函数定义中访问局部变量。

要演示,请查看以下scope.sh bash脚本:

#!/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()定义中,我使用本地关键字定义局部变量V1并修改全局变量v2.
请注意,我们可以在不同函数中使用相同的局部变量的变量名称。

现在让我们运行脚本:

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

从脚本输出中,我们可以结束以下内容:

  • 具有与全局变量相同名称的本地变量将优先于函数体内的全局变量。
  • 我们可以从函数内更改全局变量。

递归函数

递归函数是一个调用自身的函数!当我们尝试解决可以分解为较小的子问题的编程问题时,递归功能派上用场。

因子函数是递归函数的经典示例。

看看以下派分.sh bash脚本:

#!/bin/bash
factorial () {
if [  -le 1 ]; then
echo 1
else
last=$(factorial $((  -1)))
echo $((  * last ))
fi
}
echo -n "4! is: "
factorial 4
echo -n "5! is: "
factorial 5
echo -n "6! is: "
factorial 6

任何递归函数必须以基本情况开头,这必须结束递归函数调用的链。
在阶段()函数中,基本情况定义如下:

if [  -le 1 ]; then
echo 1

现在导出因子函数的递归案例。
为了计算N个是正数的数字N的阶乘,我们可以通过N-1的因子来乘以n:

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

让我们使用上面的等式来编写这个递归情况:

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

现在运行脚本并确保获得正确的结果:

Hyman@theitroad:~$./factorial.sh
4! is: 24
5! is: 120
6! is: 720